cx 26.0.11 → 26.0.13
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/charts/ScatterGraph.d.ts +4 -4
- package/build/charts/ScatterGraph.js +2 -2
- package/build/data/ArrayElementView.spec.d.ts +1 -0
- package/build/data/ArrayElementView.spec.js +81 -0
- package/build/data/Binding.spec.d.ts +1 -0
- package/build/data/Binding.spec.js +61 -0
- package/build/data/Expression.spec.d.ts +1 -0
- package/build/data/Expression.spec.js +196 -0
- package/build/data/Grouper.spec.d.ts +1 -0
- package/build/data/Grouper.spec.js +48 -0
- package/build/data/Ref.spec.d.ts +1 -0
- package/build/data/Ref.spec.js +72 -0
- package/build/data/Selector.d.ts +1 -1
- package/build/data/Store.spec.d.ts +1 -0
- package/build/data/Store.spec.js +19 -0
- package/build/data/StoreRef.spec.d.ts +1 -0
- package/build/data/StoreRef.spec.js +22 -0
- package/build/data/StringTemplate.spec.d.ts +1 -0
- package/build/data/StringTemplate.spec.js +112 -0
- package/build/data/StructuredSelector.spec.d.ts +1 -0
- package/build/data/StructuredSelector.spec.js +102 -0
- package/build/data/View.spec.d.ts +1 -0
- package/build/data/View.spec.js +44 -0
- package/build/data/ZoomIntoPropertyView.spec.d.ts +1 -0
- package/build/data/ZoomIntoPropertyView.spec.js +54 -0
- package/build/data/comparer.spec.d.ts +1 -0
- package/build/data/comparer.spec.js +50 -0
- package/build/data/computable.d.ts +3 -6
- package/build/data/computable.spec.d.ts +1 -0
- package/build/data/computable.spec.js +56 -0
- package/build/data/createAccessorModelProxy.d.ts +5 -3
- package/build/data/createAccessorModelProxy.spec.d.ts +1 -0
- package/build/data/createAccessorModelProxy.spec.js +30 -0
- package/build/data/createStructuredSelector.spec.d.ts +1 -0
- package/build/data/createStructuredSelector.spec.js +42 -0
- package/build/data/diff/diffs.spec.d.ts +1 -0
- package/build/data/diff/diffs.spec.js +45 -0
- package/build/data/getAccessor.spec.d.ts +1 -0
- package/build/data/getAccessor.spec.js +10 -0
- package/build/data/getSelector.spec.d.ts +1 -0
- package/build/data/getSelector.spec.js +36 -0
- package/build/data/ops/append.spec.d.ts +1 -0
- package/build/data/ops/append.spec.js +24 -0
- package/build/data/ops/filter.spec.d.ts +1 -0
- package/build/data/ops/filter.spec.js +25 -0
- package/build/data/ops/findTreeNode.d.ts +1 -1
- package/build/data/ops/findTreeNode.js +1 -1
- package/build/data/ops/findTreeNode.spec.d.ts +1 -0
- package/build/data/ops/findTreeNode.spec.js +20 -0
- package/build/data/ops/findTreePath.d.ts +1 -1
- package/build/data/ops/merge.spec.d.ts +1 -0
- package/build/data/ops/merge.spec.js +23 -0
- package/build/data/ops/removeTreeNodes.d.ts +1 -1
- package/build/data/ops/removeTreeNodes.js +1 -1
- package/build/data/ops/removeTreeNodes.spec.d.ts +1 -0
- package/build/data/ops/removeTreeNodes.spec.js +35 -0
- package/build/data/ops/updateArray.spec.d.ts +1 -0
- package/build/data/ops/updateArray.spec.js +33 -0
- package/build/data/ops/updateTree.d.ts +1 -1
- package/build/data/ops/updateTree.spec.d.ts +1 -0
- package/build/data/ops/updateTree.spec.js +44 -0
- package/build/hooks/invokeCallback.spec.d.ts +1 -0
- package/build/hooks/invokeCallback.spec.js +44 -0
- package/build/hooks/resolveCallback.spec.d.ts +1 -0
- package/build/hooks/resolveCallback.spec.js +35 -0
- package/build/hooks/store.spec.d.ts +1 -0
- package/build/hooks/store.spec.js +48 -0
- package/build/hooks/useTrigger.spec.d.ts +1 -0
- package/build/hooks/useTrigger.spec.js +59 -0
- package/build/jsx-runtime.d.ts +10 -10
- package/build/jsx-runtime.js +6 -0
- package/build/svg/util/Rect.d.ts +1 -1
- package/build/ui/ContentResolver.d.ts +16 -6
- package/build/ui/Controller.d.ts +7 -0
- package/build/ui/Controller.js +2 -1
- package/build/ui/Controller.spec.d.ts +1 -0
- package/build/ui/Controller.spec.js +247 -0
- package/build/ui/Cx.spec.d.ts +1 -0
- package/build/ui/Cx.spec.js +153 -0
- package/build/ui/DataProxy.spec.d.ts +1 -0
- package/build/ui/DataProxy.spec.js +208 -0
- package/build/ui/Instance.d.ts +1 -1
- package/build/ui/Instance.js +10 -10
- package/build/ui/IsolatedScope.spec.d.ts +1 -0
- package/build/ui/IsolatedScope.spec.js +42 -0
- package/build/ui/Prop.d.ts +12 -1
- package/build/ui/PureContainer.spec.d.ts +1 -0
- package/build/ui/PureContainer.spec.js +149 -0
- package/build/ui/Repeater.d.ts +3 -3
- package/build/ui/Repeater.spec.d.ts +1 -0
- package/build/ui/Repeater.spec.js +109 -0
- package/build/ui/Rescope.spec.d.ts +1 -0
- package/build/ui/Rescope.spec.js +134 -0
- package/build/ui/Restate.spec.d.ts +1 -0
- package/build/ui/Restate.spec.js +257 -0
- package/build/ui/Text.d.ts +14 -2
- package/build/ui/Text.js +3 -0
- package/build/ui/adapter/ArrayAdapter.js +4 -1
- package/build/ui/adapter/ArrayAdapter.spec.d.ts +1 -0
- package/build/ui/adapter/ArrayAdapter.spec.js +44 -0
- package/build/ui/adapter/TreeAdapter.spec.d.ts +1 -0
- package/build/ui/adapter/TreeAdapter.spec.js +71 -0
- package/build/ui/app/Url.spec.d.ts +1 -0
- package/build/ui/app/Url.spec.js +43 -0
- package/build/ui/app/startHotAppLoop.js +1 -1
- package/build/ui/createFunctionalComponent.d.ts +14 -1
- package/build/ui/createFunctionalComponent.js +7 -4
- package/build/ui/createFunctionalComponent.spec.d.ts +1 -0
- package/build/ui/createFunctionalComponent.spec.js +272 -0
- package/build/ui/expr.d.ts +3 -1
- package/build/ui/exprHelpers.d.ts +32 -0
- package/build/ui/exprHelpers.js +61 -0
- package/build/ui/index.d.ts +1 -0
- package/build/ui/index.js +1 -0
- package/build/ui/layout/ContentPlaceholder.spec.d.ts +1 -0
- package/build/ui/layout/ContentPlaceholder.spec.js +333 -0
- package/build/ui/layout/FirstVisibleChildLayout.spec.d.ts +1 -0
- package/build/ui/layout/FirstVisibleChildLayout.spec.js +101 -0
- package/build/ui/selection/KeySelection.d.ts +0 -8
- package/build/ui/selection/Selection.d.ts +9 -3
- package/build/util/Console.d.ts +1 -0
- package/build/util/Console.js +7 -3
- package/build/util/Format.spec.d.ts +1 -0
- package/build/util/Format.spec.js +58 -0
- package/build/util/TraversalStack.spec.d.ts +1 -0
- package/build/util/TraversalStack.spec.js +43 -0
- package/build/util/date/upperBoundCheck.spec.d.ts +1 -0
- package/build/util/date/upperBoundCheck.spec.js +22 -0
- package/build/util/getSearchQueryPredicate.spec.d.ts +1 -0
- package/build/util/getSearchQueryPredicate.spec.js +33 -0
- package/build/util/isValidIdentifierName.spec.d.ts +1 -0
- package/build/util/isValidIdentifierName.spec.js +28 -0
- package/build/util/routeAppend.spec.d.ts +1 -0
- package/build/util/routeAppend.spec.js +14 -0
- package/build/widgets/AccessorBindings.spec.d.ts +1 -0
- package/build/widgets/AccessorBindings.spec.js +40 -0
- package/build/widgets/Button.d.ts +3 -6
- package/build/widgets/Button.js +1 -1
- package/build/widgets/DocumentTitle.d.ts +2 -0
- package/build/widgets/Heading.d.ts +2 -2
- package/build/widgets/HtmlElement.d.ts +33 -8
- package/build/widgets/HtmlElement.js +7 -9
- package/build/widgets/HtmlElement.spec.d.ts +1 -0
- package/build/widgets/HtmlElement.spec.js +38 -0
- package/build/widgets/Icon.d.ts +3 -13
- package/build/widgets/List.d.ts +4 -0
- package/build/widgets/ReactElementWrapper.d.ts +29 -0
- package/build/widgets/ReactElementWrapper.js +59 -0
- package/build/widgets/drag-drop/DragSource.d.ts +3 -3
- package/build/widgets/drag-drop/DragSource.js +2 -3
- package/build/widgets/drag-drop/DropZone.d.ts +3 -3
- package/build/widgets/drag-drop/DropZone.js +2 -3
- package/build/widgets/form/Checkbox.d.ts +2 -0
- package/build/widgets/form/ColorField.d.ts +2 -0
- package/build/widgets/form/DateTimeField.d.ts +2 -0
- package/build/widgets/form/Field.d.ts +0 -2
- package/build/widgets/form/LabeledContainer.d.ts +9 -8
- package/build/widgets/form/LabeledContainer.js +9 -9
- package/build/widgets/form/LookupField.d.ts +57 -9
- package/build/widgets/form/MonthField.d.ts +2 -0
- package/build/widgets/form/NumberField.d.ts +2 -0
- package/build/widgets/form/Radio.d.ts +2 -0
- package/build/widgets/form/Select.d.ts +2 -0
- package/build/widgets/form/Slider.d.ts +3 -0
- package/build/widgets/form/Switch.d.ts +2 -0
- package/build/widgets/form/TextField.d.ts +34 -0
- package/build/widgets/form/TimeList.d.ts +16 -1
- package/build/widgets/form/TimeList.js +34 -62
- package/build/widgets/form/UploadButton.d.ts +34 -2
- package/build/widgets/form/UploadButton.js +3 -1
- package/build/widgets/form/ValidationGroup.spec.d.ts +1 -0
- package/build/widgets/form/ValidationGroup.spec.js +62 -0
- package/build/widgets/form/Validator.d.ts +33 -2
- package/build/widgets/form/Validator.js +3 -0
- package/build/widgets/grid/Grid.d.ts +9 -9
- package/build/widgets/grid/TreeNode.d.ts +6 -0
- package/build/widgets/index.d.ts +1 -0
- package/build/widgets/index.js +1 -0
- package/build/widgets/nav/MenuItem.d.ts +3 -2
- package/build/widgets/nav/Route.spec.d.ts +1 -0
- package/build/widgets/nav/Route.spec.js +15 -0
- package/build/widgets/nav/Scroller.d.ts +4 -6
- package/build/widgets/nav/Scroller.js +6 -3
- package/build/widgets/nav/Tab.d.ts +2 -2
- package/build/widgets/overlay/ContextMenu.d.ts +3 -3
- package/build/widgets/overlay/Overlay.d.ts +2 -1
- package/build/widgets/overlay/Overlay.js +1 -1
- package/build.js +133 -133
- package/dist/data.js +2 -2
- package/dist/jsx-runtime.js +6 -1
- package/dist/manifest.d.ts +1443 -0
- package/dist/manifest.js +852 -804
- package/dist/ui.js +91 -5
- package/dist/util.js +3 -0
- package/dist/widgets.js +520 -161
- package/package.json +46 -20
- package/src/charts/Chart.ts +108 -108
- package/src/charts/ScatterGraph.tsx +6 -6
- package/src/data/ArrayElementView.ts +90 -90
- package/src/data/AugmentedViewBase.ts +88 -88
- package/src/data/Binding.ts +104 -104
- package/src/data/ExposedRecordView.ts +95 -95
- package/src/data/ExposedValueView.ts +89 -89
- package/src/data/Expression.spec.ts +229 -229
- package/src/data/Expression.ts +233 -233
- package/src/data/Grouper.spec.ts +57 -57
- package/src/data/Grouper.ts +158 -158
- package/src/data/NestedDataView.ts +43 -43
- package/src/data/ReadOnlyDataView.ts +39 -39
- package/src/data/Ref.ts +104 -104
- package/src/data/Selector.ts +10 -10
- package/src/data/Store.ts +52 -52
- package/src/data/StoreProxy.ts +19 -19
- package/src/data/StoreRef.ts +66 -66
- package/src/data/StringTemplate.spec.ts +132 -132
- package/src/data/StringTemplate.ts +93 -93
- package/src/data/StructuredSelector.spec.ts +113 -113
- package/src/data/StructuredSelector.ts +146 -146
- package/src/data/SubscribableView.ts +63 -63
- package/src/data/ZoomIntoPropertyView.spec.ts +64 -64
- package/src/data/ZoomIntoPropertyView.ts +45 -45
- package/src/data/computable.spec.ts +87 -62
- package/src/data/computable.ts +3 -6
- package/src/data/createAccessorModelProxy.spec.tsx +102 -1
- package/src/data/createAccessorModelProxy.ts +9 -3
- 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/findTreeNode.ts +1 -5
- package/src/data/ops/findTreePath.ts +1 -1
- package/src/data/ops/merge.ts +13 -13
- package/src/data/ops/removeTreeNodes.spec.ts +37 -37
- package/src/data/ops/removeTreeNodes.ts +2 -2
- package/src/data/ops/updateArray.spec.ts +69 -69
- package/src/data/ops/updateArray.ts +31 -31
- package/src/data/ops/updateTree.ts +1 -1
- package/src/data/test-types.ts +7 -7
- package/src/hooks/resolveCallback.spec.tsx +30 -7
- package/src/hooks/useTrigger.ts +26 -26
- package/src/index.scss +6 -6
- package/src/jsx-dev-runtime.ts +4 -4
- package/src/jsx-runtime.spec.tsx +402 -0
- package/src/jsx-runtime.ts +26 -22
- package/src/svg/BoundedObject.ts +101 -101
- package/src/svg/util/Rect.ts +105 -105
- package/src/ui/CSSHelper.ts +17 -17
- package/src/ui/ContentResolver.spec.tsx +172 -19
- package/src/ui/ContentResolver.ts +16 -8
- package/src/ui/Controller.ts +15 -2
- package/src/ui/Culture.ts +159 -159
- package/src/ui/DataProxy.ts +55 -55
- package/src/ui/FocusManager.ts +171 -171
- package/src/ui/Instance.ts +866 -868
- package/src/ui/Prop.ts +140 -112
- package/src/ui/RenderingContext.ts +99 -99
- package/src/ui/Repeater.ts +3 -12
- package/src/ui/Rescope.ts +49 -49
- package/src/ui/StructuredInstanceDataAccessor.ts +32 -32
- package/src/ui/Text.ts +21 -2
- package/src/ui/VDOM.ts +34 -34
- package/src/ui/adapter/ArrayAdapter.spec.ts +55 -55
- package/src/ui/adapter/ArrayAdapter.ts +4 -1
- 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/startHotAppLoop.ts +41 -41
- package/src/ui/createFunctionalComponent.spec.tsx +53 -0
- package/src/ui/createFunctionalComponent.ts +86 -65
- package/src/ui/expr.ts +4 -1
- package/src/ui/exprHelpers.spec.ts +379 -0
- package/src/ui/exprHelpers.ts +78 -0
- package/src/ui/index.ts +47 -46
- package/src/ui/layout/Content.ts +30 -30
- package/src/ui/layout/FirstVisibleChildLayout.spec.tsx +1 -1
- package/src/ui/layout/FirstVisibleChildLayout.ts +60 -60
- package/src/ui/selection/KeySelection.ts +0 -12
- package/src/ui/selection/PropertySelection.ts +87 -87
- package/src/ui/selection/Selection.ts +13 -3
- package/src/util/Console.ts +13 -11
- package/src/util/Format.ts +267 -267
- package/src/util/addEventListenerWithOptions.ts +41 -41
- package/src/util/browserSupportsPassiveEventHandlers.ts +20 -20
- package/src/util/color/rgbToHsl.ts +35 -35
- package/src/util/getActiveElement.ts +4 -4
- package/src/util/hasKey.ts +18 -18
- package/src/util/index.ts +55 -55
- package/src/util/innerTextTrim.ts +10 -10
- package/src/util/isArray.ts +3 -3
- package/src/util/isDataRecord.ts +5 -5
- package/src/util/isDefined.ts +3 -3
- package/src/util/isString.ts +3 -3
- package/src/widgets/AccessorBindings.spec.tsx +26 -0
- package/src/widgets/Button.tsx +5 -17
- package/src/widgets/DocumentTitle.ts +95 -92
- package/src/widgets/Heading.ts +2 -2
- package/src/widgets/HtmlElement.spec.helpers.tsx +108 -0
- package/src/widgets/HtmlElement.spec.tsx +20 -12
- package/src/widgets/HtmlElement.tsx +82 -24
- package/src/widgets/Icon.ts +3 -17
- package/src/widgets/List.tsx +6 -0
- package/src/widgets/ReactElementWrapper.spec.tsx +452 -0
- package/src/widgets/ReactElementWrapper.tsx +108 -0
- package/src/widgets/Sandbox.ts +103 -103
- package/src/widgets/autoFocus.ts +9 -9
- package/src/widgets/cx.ts +63 -63
- package/src/widgets/drag-drop/DragSource.tsx +3 -4
- package/src/widgets/drag-drop/DropZone.tsx +3 -4
- package/src/widgets/form/Checkbox.tsx +3 -0
- package/src/widgets/form/ColorField.tsx +3 -0
- package/src/widgets/form/DateTimeField.tsx +5 -0
- package/src/widgets/form/Field.tsx +0 -3
- package/src/widgets/form/Label.tsx +1 -0
- package/src/widgets/form/LabeledContainer.ts +22 -26
- package/src/widgets/form/LookupField.spec.tsx +93 -0
- package/src/widgets/form/LookupField.tsx +104 -9
- package/src/widgets/form/MonthField.tsx +5 -0
- package/src/widgets/form/NumberField.tsx +3 -0
- package/src/widgets/form/Radio.tsx +5 -0
- package/src/widgets/form/Select.tsx +5 -0
- package/src/widgets/form/Slider.tsx +4 -0
- package/src/widgets/form/Switch.tsx +3 -0
- package/src/widgets/form/TextField.tsx +62 -0
- package/src/widgets/form/TimeList.tsx +84 -73
- package/src/widgets/form/UploadButton.tsx +53 -2
- package/src/widgets/form/Validator.ts +40 -3
- package/src/widgets/grid/Grid.tsx +9 -12
- package/src/widgets/grid/GridCell.ts +143 -143
- package/src/widgets/grid/TreeNode.tsx +9 -0
- package/src/widgets/icons/calendar.tsx +17 -17
- package/src/widgets/icons/check.tsx +13 -13
- package/src/widgets/icons/clear.tsx +15 -15
- package/src/widgets/icons/close.tsx +20 -20
- package/src/widgets/icons/cx.tsx +38 -38
- package/src/widgets/icons/drop-down.tsx +15 -15
- package/src/widgets/icons/file.tsx +13 -13
- package/src/widgets/icons/folder-open.tsx +15 -15
- package/src/widgets/icons/folder.tsx +13 -13
- package/src/widgets/icons/forward.tsx +22 -22
- package/src/widgets/icons/loading.tsx +24 -24
- package/src/widgets/icons/menu.tsx +17 -17
- package/src/widgets/icons/pixel-picker.tsx +18 -18
- package/src/widgets/icons/search.tsx +13 -13
- package/src/widgets/icons/sort-asc.tsx +14 -14
- package/src/widgets/icons/square.tsx +18 -18
- package/src/widgets/index.ts +1 -0
- package/src/widgets/nav/MenuItem.tsx +3 -2
- package/src/widgets/nav/Route.ts +142 -142
- package/src/widgets/nav/Scroller.tsx +8 -9
- package/src/widgets/nav/Tab.ts +2 -2
- package/src/widgets/overlay/ContextMenu.ts +42 -42
- package/src/widgets/overlay/Dropdown.tsx +762 -762
- package/src/widgets/overlay/MsgBox.tsx +141 -141
- package/src/widgets/overlay/Overlay.tsx +5 -4
- package/src/widgets/overlay/Toast.ts +111 -111
- package/src/widgets/overlay/Window.tsx +299 -299
- package/src/widgets/overlay/alerts.ts +46 -46
- package/src/widgets/overlay/captureMouse.ts +195 -195
- package/src/widgets/overlay/createHotPromiseWindowFactory.ts +72 -72
- package/src/widgets/overlay/index.d.ts +11 -11
- package/src/widgets/overlay/index.ts +11 -11
- package/src/widgets/overlay/tooltip-ops.ts +173 -173
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx as _jsx } from "cx/jsx-runtime";
|
|
2
|
+
import { Store } from "../data/Store";
|
|
3
|
+
import { createTestRenderer } from "../util/test/createTestRenderer";
|
|
4
|
+
import assert from "assert";
|
|
5
|
+
import { IsolatedScope } from "./IsolatedScope";
|
|
6
|
+
import { bind } from "./bind";
|
|
7
|
+
describe("IsolatedScope", () => {
|
|
8
|
+
it("prevents multiple re-renders", () => {
|
|
9
|
+
let list = [];
|
|
10
|
+
let widget = (_jsx("cx", { children: _jsx(IsolatedScope, { data: {
|
|
11
|
+
value: { bind: 'value' }
|
|
12
|
+
}, children: _jsx("span", { text: bind("value"), onExplore: (context, { store }) => {
|
|
13
|
+
list.push(store.get("value"));
|
|
14
|
+
} }) }) }));
|
|
15
|
+
let store = new Store({
|
|
16
|
+
data: {
|
|
17
|
+
value: "bad",
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
const component = createTestRenderer(store, widget);
|
|
21
|
+
let tree = component.toJSON();
|
|
22
|
+
assert.deepEqual(list, ["bad"]);
|
|
23
|
+
assert.deepEqual(tree, {
|
|
24
|
+
type: "span",
|
|
25
|
+
props: {},
|
|
26
|
+
children: ["bad"],
|
|
27
|
+
});
|
|
28
|
+
//component should not re-render if unrelated data changes
|
|
29
|
+
store.set("dummy", "dummy");
|
|
30
|
+
tree = component.toJSON();
|
|
31
|
+
assert.deepEqual(list, ["bad"]);
|
|
32
|
+
//component should not re-render if unrelated data changes
|
|
33
|
+
store.set("value", "good");
|
|
34
|
+
tree = component.toJSON();
|
|
35
|
+
assert.deepEqual(list, ["bad", "good"]);
|
|
36
|
+
assert.deepEqual(tree, {
|
|
37
|
+
type: "span",
|
|
38
|
+
props: {},
|
|
39
|
+
children: ["good"],
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
});
|
package/build/ui/Prop.d.ts
CHANGED
|
@@ -45,9 +45,20 @@ export type ResolveProp<P> = P extends Selector<infer T> ? T : P extends Accesso
|
|
|
45
45
|
* Utility type that resolves a structured prop object to its runtime value types.
|
|
46
46
|
* Transforms { name: StringProp, count: NumberProp } to { name: string, count: number }
|
|
47
47
|
*/
|
|
48
|
-
export type
|
|
48
|
+
export type ResolveStructuredPropType<S> = {
|
|
49
49
|
[K in keyof S]: ResolveProp<S[K]>;
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Resolves the runtime value type from either a Prop<T> or a StructuredProp.
|
|
53
|
+
* Use this for generic widgets like ContentResolver and Validator where the
|
|
54
|
+
* input can be either a single prop or a structured object.
|
|
55
|
+
*
|
|
56
|
+
* - For Prop<T> (Selector, AccessorChain, GetSet), resolves to T
|
|
57
|
+
* - For bindings (Bind, Tpl, Expr), resolves to any/string/any
|
|
58
|
+
* - For structured objects, recursively resolves each property via ResolveStructuredProp
|
|
59
|
+
* - For literal values, returns them as-is
|
|
60
|
+
*/
|
|
61
|
+
export type ResolvePropType<P> = P extends Selector<infer T> ? T : P extends AccessorChain<infer T> ? T : P extends GetSet<infer T> ? T : P extends Bind ? any : P extends Tpl ? string : P extends Expr ? any : P extends object ? ResolveStructuredPropType<P> : P;
|
|
51
62
|
/**
|
|
52
63
|
* Generic structured prop type that provides type safety for params and their resolved values.
|
|
53
64
|
* Use with ContentResolver and similar widgets to type the onResolve callback params.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "cx/jsx-runtime";
|
|
2
|
+
import { Store } from "../data/Store";
|
|
3
|
+
import assert from "assert";
|
|
4
|
+
import { createTestRenderer } from "../util/test/createTestRenderer";
|
|
5
|
+
import { bind } from "./bind";
|
|
6
|
+
import { PureContainer } from "./PureContainer";
|
|
7
|
+
describe("PureContainer", () => {
|
|
8
|
+
it("renders static text children", () => {
|
|
9
|
+
let widget = (_jsx("cx", { children: _jsx(PureContainer, { children: _jsx("div", { children: "Test" }) }) }));
|
|
10
|
+
let store = new Store();
|
|
11
|
+
const component = createTestRenderer(store, widget);
|
|
12
|
+
let tree = component.toJSON();
|
|
13
|
+
assert(tree && !Array.isArray(tree), "Expected single element");
|
|
14
|
+
assert.deepEqual(tree, {
|
|
15
|
+
type: "div",
|
|
16
|
+
props: {},
|
|
17
|
+
children: ["Test"],
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
it("renders multiple children", () => {
|
|
21
|
+
let widget = (_jsx("cx", { children: _jsxs(PureContainer, { children: [_jsx("div", { children: "First" }), _jsx("div", { children: "Second" }), _jsx("div", { children: "Third" })] }) }));
|
|
22
|
+
let store = new Store();
|
|
23
|
+
const component = createTestRenderer(store, widget);
|
|
24
|
+
let tree = component.toJSON();
|
|
25
|
+
assert(Array.isArray(tree), "Expected array of elements");
|
|
26
|
+
assert.equal(tree.length, 3);
|
|
27
|
+
assert.deepEqual(tree, [
|
|
28
|
+
{
|
|
29
|
+
type: "div",
|
|
30
|
+
props: {},
|
|
31
|
+
children: ["First"],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: "div",
|
|
35
|
+
props: {},
|
|
36
|
+
children: ["Second"],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
type: "div",
|
|
40
|
+
props: {},
|
|
41
|
+
children: ["Third"],
|
|
42
|
+
},
|
|
43
|
+
]);
|
|
44
|
+
});
|
|
45
|
+
it("renders children with data bindings", () => {
|
|
46
|
+
let widget = (_jsx("cx", { children: _jsx(PureContainer, { children: _jsx("div", { text: bind("message") }) }) }));
|
|
47
|
+
let store = new Store({
|
|
48
|
+
data: {
|
|
49
|
+
message: "Hello World",
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
const component = createTestRenderer(store, widget);
|
|
53
|
+
let tree = component.toJSON();
|
|
54
|
+
assert(tree && !Array.isArray(tree), "Expected single element");
|
|
55
|
+
assert.deepEqual(tree, {
|
|
56
|
+
type: "div",
|
|
57
|
+
props: {},
|
|
58
|
+
children: ["Hello World"],
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
it("renders nested containers", () => {
|
|
62
|
+
let widget = (_jsx("cx", { children: _jsx(PureContainer, { children: _jsx("div", { children: _jsx(PureContainer, { children: _jsx("span", { children: "Nested" }) }) }) }) }));
|
|
63
|
+
let store = new Store();
|
|
64
|
+
const component = createTestRenderer(store, widget);
|
|
65
|
+
let tree = component.toJSON();
|
|
66
|
+
assert(tree && !Array.isArray(tree), "Expected single element");
|
|
67
|
+
assert.deepEqual(tree, {
|
|
68
|
+
type: "div",
|
|
69
|
+
props: {},
|
|
70
|
+
children: [
|
|
71
|
+
{
|
|
72
|
+
type: "span",
|
|
73
|
+
props: {},
|
|
74
|
+
children: ["Nested"],
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
it("conditionally renders children based on visible binding", () => {
|
|
80
|
+
let widget = (_jsx("cx", { children: _jsxs(PureContainer, { children: [_jsx("div", { visible: bind("show"), text: "Visible" }), _jsx("div", { visible: false, text: "Hidden" })] }) }));
|
|
81
|
+
let store = new Store({
|
|
82
|
+
data: {
|
|
83
|
+
show: true,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
const component = createTestRenderer(store, widget);
|
|
87
|
+
let tree = component.toJSON();
|
|
88
|
+
assert(tree && !Array.isArray(tree), "Expected single element");
|
|
89
|
+
assert.deepEqual(tree, {
|
|
90
|
+
type: "div",
|
|
91
|
+
props: {},
|
|
92
|
+
children: ["Visible"],
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
it("handles empty children", () => {
|
|
96
|
+
let widget = (_jsx("cx", { children: _jsx(PureContainer, { children: _jsx("div", {}) }) }));
|
|
97
|
+
let store = new Store();
|
|
98
|
+
const component = createTestRenderer(store, widget);
|
|
99
|
+
let tree = component.toJSON();
|
|
100
|
+
assert(tree && !Array.isArray(tree), "Expected single element");
|
|
101
|
+
assert.deepEqual(tree, {
|
|
102
|
+
type: "div",
|
|
103
|
+
props: {},
|
|
104
|
+
children: null,
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
it("renders children from items property", () => {
|
|
108
|
+
let widget = (_jsx("cx", { children: _jsx(PureContainer, { items: [_jsx("div", { children: "Item 1" }, "1"), _jsx("div", { children: "Item 2" }, "2")] }) }));
|
|
109
|
+
let store = new Store();
|
|
110
|
+
const component = createTestRenderer(store, widget);
|
|
111
|
+
let tree = component.toJSON();
|
|
112
|
+
assert(Array.isArray(tree), "Expected array of elements");
|
|
113
|
+
assert.equal(tree.length, 2);
|
|
114
|
+
assert.deepEqual(tree[0], {
|
|
115
|
+
type: "div",
|
|
116
|
+
props: {},
|
|
117
|
+
children: ["Item 1"],
|
|
118
|
+
});
|
|
119
|
+
assert.deepEqual(tree[1], {
|
|
120
|
+
type: "div",
|
|
121
|
+
props: {},
|
|
122
|
+
children: ["Item 2"],
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
it("updates children when store data changes", () => {
|
|
126
|
+
let widget = (_jsx("cx", { children: _jsx(PureContainer, { children: _jsx("div", { text: bind("count") }) }) }));
|
|
127
|
+
let store = new Store({
|
|
128
|
+
data: {
|
|
129
|
+
count: 0,
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
const component = createTestRenderer(store, widget);
|
|
133
|
+
let tree = component.toJSON();
|
|
134
|
+
assert.deepEqual(tree, {
|
|
135
|
+
type: "div",
|
|
136
|
+
props: {},
|
|
137
|
+
children: ["0"],
|
|
138
|
+
});
|
|
139
|
+
// Update the store
|
|
140
|
+
store.set("count", 5);
|
|
141
|
+
// Re-render
|
|
142
|
+
tree = component.toJSON();
|
|
143
|
+
assert.deepEqual(tree, {
|
|
144
|
+
type: "div",
|
|
145
|
+
props: {},
|
|
146
|
+
children: ["5"],
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
});
|
package/build/ui/Repeater.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { ContainerBase, ContainerConfig } from "./Container";
|
|
2
2
|
import { ArrayAdapter } from "./adapter/ArrayAdapter";
|
|
3
3
|
import { RenderingContext } from "./RenderingContext";
|
|
4
|
-
import { Prop, StringProp, StructuredProp, RecordAlias, SortersProp, CollatorOptions, SortDirection
|
|
4
|
+
import { Prop, StringProp, StructuredProp, RecordAlias, SortersProp, CollatorOptions, SortDirection } from "./Prop";
|
|
5
5
|
import { Instance } from "./Instance";
|
|
6
6
|
import { DataAdapter, DataAdapterRecord } from "./adapter/DataAdapter";
|
|
7
7
|
import type { GroupAdapter } from "./adapter/GroupAdapter";
|
|
8
8
|
import type { TreeAdapter } from "./adapter/TreeAdapter";
|
|
9
9
|
import { Create } from "../util/Component";
|
|
10
|
-
export interface RepeaterConfig<T =
|
|
10
|
+
export interface RepeaterConfig<T = any> extends ContainerConfig {
|
|
11
11
|
/** An array of records to be displayed. */
|
|
12
12
|
records?: Prop<T[]>;
|
|
13
13
|
/** Alias used to expose the record in the child scope. Default is `$record`. */
|
|
@@ -47,7 +47,7 @@ export interface RepeaterConfig<T = DataRecord> extends ContainerConfig {
|
|
|
47
47
|
/** Data adapter used to convert data in the list of records. Used for manipulation of records, e.g flattening the tree records. */
|
|
48
48
|
dataAdapter?: Create<typeof DataAdapter> | Create<typeof ArrayAdapter> | Create<typeof TreeAdapter> | Create<typeof GroupAdapter>;
|
|
49
49
|
}
|
|
50
|
-
export declare class Repeater<
|
|
50
|
+
export declare class Repeater<T = any> extends ContainerBase<RepeaterConfig<T>> {
|
|
51
51
|
records?: any;
|
|
52
52
|
recordsAccessor: any;
|
|
53
53
|
recordAlias?: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { jsx as _jsx } from "cx/jsx-runtime";
|
|
2
|
+
import { Store } from "../data/Store";
|
|
3
|
+
import { Repeater } from "./Repeater";
|
|
4
|
+
import { bind } from "./bind";
|
|
5
|
+
import { createTestRenderer } from "../util/test/createTestRenderer";
|
|
6
|
+
import assert from "assert";
|
|
7
|
+
describe("Repeater", () => {
|
|
8
|
+
it("allows sorting", () => {
|
|
9
|
+
let data = [
|
|
10
|
+
{
|
|
11
|
+
value: "C",
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
value: "B",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
value: "A",
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
let widget = (_jsx("cx", { children: _jsx("div", { children: _jsx(Repeater, { records: data, sorters: [{ field: "value", direction: "ASC" }], recordAlias: "$item", children: _jsx("div", { text: bind("$item.value") }) }) }) }));
|
|
21
|
+
let store = new Store();
|
|
22
|
+
const component = createTestRenderer(store, widget);
|
|
23
|
+
let tree = component.toJSON();
|
|
24
|
+
assert.deepEqual(tree, {
|
|
25
|
+
type: "div",
|
|
26
|
+
props: {},
|
|
27
|
+
children: [
|
|
28
|
+
{
|
|
29
|
+
type: "div",
|
|
30
|
+
props: {},
|
|
31
|
+
children: ["A"],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: "div",
|
|
35
|
+
props: {},
|
|
36
|
+
children: ["B"],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
type: "div",
|
|
40
|
+
props: {},
|
|
41
|
+
children: ["C"],
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
it("changes are properly updated", () => {
|
|
47
|
+
let divInstances = [];
|
|
48
|
+
let widget = (_jsx("cx", { children: _jsx("div", { children: _jsx(Repeater, { records: bind("data"), sorters: [{ field: "value", direction: "ASC" }], recordAlias: "$item", children: _jsx("div", { text: bind("$item.value"), onExplore: (context, instance) => {
|
|
49
|
+
divInstances.push(instance);
|
|
50
|
+
} }) }) }) }));
|
|
51
|
+
let store = new Store({
|
|
52
|
+
data: {
|
|
53
|
+
data: [
|
|
54
|
+
{
|
|
55
|
+
value: "C",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
value: "B",
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
const component = createTestRenderer(store, widget);
|
|
64
|
+
let tree = component.toJSON();
|
|
65
|
+
assert.deepEqual(tree, {
|
|
66
|
+
type: "div",
|
|
67
|
+
props: {},
|
|
68
|
+
children: [
|
|
69
|
+
{
|
|
70
|
+
type: "div",
|
|
71
|
+
props: {},
|
|
72
|
+
children: ["B"],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: "div",
|
|
76
|
+
props: {},
|
|
77
|
+
children: ["C"],
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
});
|
|
81
|
+
divInstances = [];
|
|
82
|
+
store.update("data", (data) => [{ value: "A" }, ...data]);
|
|
83
|
+
assert.deepEqual(component.toJSON(), {
|
|
84
|
+
type: "div",
|
|
85
|
+
props: {},
|
|
86
|
+
children: [
|
|
87
|
+
{
|
|
88
|
+
type: "div",
|
|
89
|
+
props: {},
|
|
90
|
+
children: ["A"],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
type: "div",
|
|
94
|
+
props: {},
|
|
95
|
+
children: ["B"],
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
type: "div",
|
|
99
|
+
props: {},
|
|
100
|
+
children: ["C"],
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
});
|
|
104
|
+
assert.equal(divInstances.length, 3);
|
|
105
|
+
assert.equal(divInstances[0].store.get("$item.value"), "A");
|
|
106
|
+
assert.equal(divInstances[1].store.get("$item.value"), "B");
|
|
107
|
+
assert.equal(divInstances[2].store.get("$item.value"), "C");
|
|
108
|
+
});
|
|
109
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "cx/jsx-runtime";
|
|
2
|
+
import { Store } from "../data/Store";
|
|
3
|
+
import { Rescope } from "./Rescope";
|
|
4
|
+
import { bind } from "./bind";
|
|
5
|
+
import { createTestRenderer } from "../util/test/createTestRenderer";
|
|
6
|
+
import { Controller } from "./Controller";
|
|
7
|
+
import assert from "assert";
|
|
8
|
+
import { PureContainer } from "./PureContainer";
|
|
9
|
+
describe("Rescope", () => {
|
|
10
|
+
it("allows simple access to nested data", () => {
|
|
11
|
+
let store = new Store({
|
|
12
|
+
data: {
|
|
13
|
+
$page: {
|
|
14
|
+
data: {
|
|
15
|
+
name: "John",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
let widget = (_jsx("cx", { children: _jsx(Rescope, { bind: "$page.data", children: _jsx("div", { text: bind("name") }) }) }));
|
|
21
|
+
const component = createTestRenderer(store, widget);
|
|
22
|
+
let tree = component.toJSON();
|
|
23
|
+
assert.deepEqual(tree, {
|
|
24
|
+
type: "div",
|
|
25
|
+
props: {},
|
|
26
|
+
children: ["John"],
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
it("allows parent access through $root", () => {
|
|
30
|
+
let store = new Store({
|
|
31
|
+
data: {
|
|
32
|
+
layout: {
|
|
33
|
+
title: "Title",
|
|
34
|
+
},
|
|
35
|
+
$page: {
|
|
36
|
+
data: {
|
|
37
|
+
name: "John",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
let widget = (_jsx("cx", { children: _jsx(Rescope, { bind: "$page.data", children: _jsx("div", { text: bind("$root.layout.title") }) }) }));
|
|
43
|
+
const component = createTestRenderer(store, widget);
|
|
44
|
+
let tree = component.toJSON();
|
|
45
|
+
assert.deepEqual(tree, {
|
|
46
|
+
type: "div",
|
|
47
|
+
props: {},
|
|
48
|
+
children: ["Title"],
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
it("allows nested data access through data", () => {
|
|
52
|
+
let store = new Store({
|
|
53
|
+
data: {
|
|
54
|
+
layout: {
|
|
55
|
+
title: "Title",
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
let widget = (_jsx("cx", { children: _jsx(Rescope, { bind: "$page", data: { $title: { bind: "layout.title" } }, children: _jsx("div", { text: bind("$title") }) }) }));
|
|
60
|
+
const component = createTestRenderer(store, widget);
|
|
61
|
+
let tree = component.toJSON();
|
|
62
|
+
assert.deepEqual(tree, {
|
|
63
|
+
type: "div",
|
|
64
|
+
props: {},
|
|
65
|
+
children: ["Title"],
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
it("nested data mutations are correctly propagated to the parent store", () => {
|
|
69
|
+
let store = new Store({
|
|
70
|
+
data: {
|
|
71
|
+
item: {
|
|
72
|
+
value: 0,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
let widget = (_jsxs("cx", { children: [_jsx(Rescope, { bind: "$page", data: { $value: { bind: "item.value" } }, children: _jsx(PureContainer, { controller: {
|
|
77
|
+
onInit() {
|
|
78
|
+
this.store.set("$value", 2);
|
|
79
|
+
},
|
|
80
|
+
} }) }), _jsx("div", { text: bind("item.value") })] }));
|
|
81
|
+
const component = createTestRenderer(store, widget);
|
|
82
|
+
let tree = component.toJSON();
|
|
83
|
+
assert.deepEqual(tree, {
|
|
84
|
+
type: "div",
|
|
85
|
+
props: {},
|
|
86
|
+
children: ["2"],
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
it("visible is calculated based on the inner scope", () => {
|
|
90
|
+
let store = new Store({
|
|
91
|
+
data: {
|
|
92
|
+
layout: {
|
|
93
|
+
title: "Title",
|
|
94
|
+
},
|
|
95
|
+
$page: {
|
|
96
|
+
data: {
|
|
97
|
+
visible: true,
|
|
98
|
+
name: "John",
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
let widget = (_jsx("cx", { children: _jsx(Rescope, { bind: "$page.data", visible: bind("visible"), children: _jsx("div", { text: bind("name") }) }) }));
|
|
104
|
+
const component = createTestRenderer(store, widget);
|
|
105
|
+
let tree = component.toJSON();
|
|
106
|
+
assert.deepEqual(tree, {
|
|
107
|
+
type: "div",
|
|
108
|
+
props: {},
|
|
109
|
+
children: ["John"],
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
it("controllers see inner scope", () => {
|
|
113
|
+
let store = new Store({
|
|
114
|
+
data: {
|
|
115
|
+
$page: {
|
|
116
|
+
data: {
|
|
117
|
+
visible: true,
|
|
118
|
+
name: "John",
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
let testName = null;
|
|
124
|
+
class TestController extends Controller {
|
|
125
|
+
onInit() {
|
|
126
|
+
testName = this.store.get("name");
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
let widget = (_jsx("cx", { children: _jsx(Rescope, { bind: "$page.data", controller: TestController, children: _jsx("div", { text: bind("name") }) }) }));
|
|
130
|
+
const component = createTestRenderer(store, widget);
|
|
131
|
+
component.toJSON();
|
|
132
|
+
assert.equal(testName, "John");
|
|
133
|
+
});
|
|
134
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|