cx 26.1.0 → 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.
Files changed (113) hide show
  1. package/build/ui/Widget.js +0 -5
  2. package/build/util/Component.js +5 -0
  3. package/build/util/test/createTestRenderer.d.ts +3 -1
  4. package/build/util/test/createTestRenderer.js +8 -2
  5. package/build/widgets/icons/calendar.js +4 -3
  6. package/build/widgets/icons/check.js +2 -2
  7. package/build/widgets/icons/clear.js +2 -2
  8. package/build/widgets/icons/close.js +2 -2
  9. package/build/widgets/icons/cx.js +2 -2
  10. package/build/widgets/icons/drop-down.js +2 -2
  11. package/build/widgets/icons/file.js +2 -2
  12. package/build/widgets/icons/folder-open.js +2 -2
  13. package/build/widgets/icons/folder.js +2 -2
  14. package/build/widgets/icons/forward.js +2 -2
  15. package/build/widgets/icons/loading.js +2 -2
  16. package/build/widgets/icons/menu.js +2 -2
  17. package/build/widgets/icons/pixel-picker.js +2 -2
  18. package/build/widgets/icons/search.js +2 -2
  19. package/build/widgets/icons/sort-asc.js +2 -2
  20. package/build/widgets/icons/square.js +2 -2
  21. package/dist/manifest.js +896 -896
  22. package/dist/ui.js +1 -8
  23. package/dist/util.js +4 -0
  24. package/dist/widgets.js +377 -313
  25. package/package.json +3 -1
  26. package/src/core.d.ts +182 -182
  27. package/src/data/ArrayElementView.ts +90 -90
  28. package/src/data/AugmentedViewBase.ts +88 -88
  29. package/src/data/Binding.ts +104 -104
  30. package/src/data/ExposedRecordView.ts +95 -95
  31. package/src/data/ExposedValueView.ts +89 -89
  32. package/src/data/Grouper.spec.ts +57 -57
  33. package/src/data/NestedDataView.ts +43 -43
  34. package/src/data/ReadOnlyDataView.ts +39 -39
  35. package/src/data/Ref.ts +104 -104
  36. package/src/data/Store.ts +52 -52
  37. package/src/data/StoreProxy.ts +19 -19
  38. package/src/data/StoreRef.ts +66 -66
  39. package/src/data/StringTemplate.ts +93 -93
  40. package/src/data/StructuredSelector.spec.ts +113 -113
  41. package/src/data/SubscribableView.ts +63 -63
  42. package/src/data/ZoomIntoPropertyView.ts +45 -45
  43. package/src/data/comparer.ts +78 -78
  44. package/src/data/ops/updateArray.ts +31 -31
  45. package/src/hooks/invokeCallback.spec.tsx +4 -4
  46. package/src/hooks/resolveCallback.spec.tsx +4 -4
  47. package/src/hooks/store.spec.tsx +15 -15
  48. package/src/hooks/useTrigger.spec.tsx +16 -10
  49. package/src/jsx-dev-runtime.ts +4 -4
  50. package/src/jsx-runtime.ts +79 -79
  51. package/src/ui/CSS.ts +87 -87
  52. package/src/ui/ContentResolver.spec.tsx +31 -29
  53. package/src/ui/Controller.spec.tsx +47 -39
  54. package/src/ui/Cx.spec.tsx +10 -8
  55. package/src/ui/DataProxy.spec.tsx +18 -18
  56. package/src/ui/DataProxy.ts +55 -55
  57. package/src/ui/FocusManager.ts +171 -171
  58. package/src/ui/IsolatedScope.spec.tsx +16 -9
  59. package/src/ui/PureContainer.spec.tsx +20 -18
  60. package/src/ui/Repeater.spec.tsx +8 -6
  61. package/src/ui/Rescope.spec.tsx +13 -13
  62. package/src/ui/Rescope.ts +49 -49
  63. package/src/ui/Restate.spec.tsx +31 -27
  64. package/src/ui/VDOM.ts +1 -1
  65. package/src/ui/Widget.tsx +0 -7
  66. package/src/ui/adapter/ArrayAdapter.spec.ts +55 -55
  67. package/src/ui/createFunctionalComponent.spec.tsx +20 -18
  68. package/src/ui/layout/Content.ts +30 -30
  69. package/src/ui/layout/ContentPlaceholder.spec.tsx +46 -34
  70. package/src/ui/layout/FirstVisibleChildLayout.spec.tsx +31 -19
  71. package/src/ui/selection/PropertySelection.ts +87 -87
  72. package/src/util/Component.spec.ts +30 -0
  73. package/src/util/Component.ts +301 -296
  74. package/src/util/DOM.ts +88 -88
  75. package/src/util/Format.spec.ts +69 -69
  76. package/src/util/Format.ts +267 -267
  77. package/src/util/addEventListenerWithOptions.ts +41 -41
  78. package/src/util/browserSupportsPassiveEventHandlers.ts +20 -20
  79. package/src/util/color/rgbToHsl.ts +35 -35
  80. package/src/util/getActiveElement.ts +4 -4
  81. package/src/util/innerTextTrim.ts +10 -10
  82. package/src/util/isDataRecord.ts +5 -5
  83. package/src/util/test/createTestRenderer.tsx +9 -2
  84. package/src/widgets/AccessorBindings.spec.tsx +4 -4
  85. package/src/widgets/HtmlElement.spec.tsx +6 -6
  86. package/src/widgets/ReactElementWrapper.spec.tsx +37 -37
  87. package/src/widgets/Sandbox.ts +103 -103
  88. package/src/widgets/form/ValidationGroup.spec.tsx +12 -12
  89. package/src/widgets/grid/GridCell.ts +143 -143
  90. package/src/widgets/icons/calendar.tsx +22 -17
  91. package/src/widgets/icons/check.tsx +14 -13
  92. package/src/widgets/icons/clear.tsx +16 -15
  93. package/src/widgets/icons/close.tsx +20 -20
  94. package/src/widgets/icons/cx.tsx +39 -38
  95. package/src/widgets/icons/drop-down.tsx +16 -15
  96. package/src/widgets/icons/file.tsx +14 -13
  97. package/src/widgets/icons/folder-open.tsx +16 -15
  98. package/src/widgets/icons/folder.tsx +14 -13
  99. package/src/widgets/icons/forward.tsx +23 -22
  100. package/src/widgets/icons/loading.tsx +25 -24
  101. package/src/widgets/icons/menu.tsx +18 -17
  102. package/src/widgets/icons/pixel-picker.tsx +18 -18
  103. package/src/widgets/icons/search.tsx +14 -13
  104. package/src/widgets/icons/sort-asc.tsx +15 -14
  105. package/src/widgets/icons/square.tsx +19 -18
  106. package/src/widgets/nav/Route.spec.tsx +2 -2
  107. package/src/widgets/nav/Route.ts +142 -142
  108. package/src/widgets/overlay/Dropdown.tsx +762 -762
  109. package/src/widgets/overlay/MsgBox.tsx +141 -141
  110. package/src/widgets/overlay/Toast.ts +111 -111
  111. package/src/widgets/overlay/Window.tsx +299 -299
  112. package/src/widgets/overlay/alerts.ts +46 -46
  113. package/src/widgets/overlay/index.ts +11 -11
@@ -1,6 +1,6 @@
1
1
  import { Store } from "../../data/Store";
2
2
  import { expr } from "../expr";
3
- import { createTestRenderer } from "../../util/test/createTestRenderer";
3
+ import { createTestRenderer, act } from "../../util/test/createTestRenderer";
4
4
 
5
5
  import assert from "assert";
6
6
  import { FirstVisibleChildLayout } from "./FirstVisibleChildLayout";
@@ -9,7 +9,7 @@ import { PureContainer } from "../PureContainer";
9
9
  import { createFunctionalComponent } from "../createFunctionalComponent";
10
10
 
11
11
  describe("FirstVisibleChildLayout", () => {
12
- it("renders only the first child", () => {
12
+ it("renders only the first child", async () => {
13
13
  let widget = (
14
14
  <cx>
15
15
  <div layout={FirstVisibleChildLayout}>
@@ -22,7 +22,7 @@ describe("FirstVisibleChildLayout", () => {
22
22
 
23
23
  let store = new Store();
24
24
 
25
- const component = createTestRenderer(store, widget);
25
+ const component = await createTestRenderer(store, widget);
26
26
 
27
27
  let tree = component.toJSON();
28
28
  assert.deepEqual(tree, {
@@ -32,7 +32,7 @@ describe("FirstVisibleChildLayout", () => {
32
32
  });
33
33
  });
34
34
 
35
- it("does not process other widgets", () => {
35
+ it("does not process other widgets", async () => {
36
36
  let h = false,
37
37
  m = false,
38
38
  f = false;
@@ -61,7 +61,7 @@ describe("FirstVisibleChildLayout", () => {
61
61
 
62
62
  let store = new Store();
63
63
 
64
- const component = createTestRenderer(store, widget);
64
+ const component = await createTestRenderer(store, widget);
65
65
 
66
66
  let tree = component.toJSON();
67
67
  assert.deepEqual(tree, {
@@ -75,7 +75,7 @@ describe("FirstVisibleChildLayout", () => {
75
75
  assert.equal(f, false);
76
76
  });
77
77
 
78
- it("skips the first child if not visible", () => {
78
+ it("skips the first child if not visible", async () => {
79
79
  let widget = (
80
80
  <cx>
81
81
  <div layout={FirstVisibleChildLayout}>
@@ -88,7 +88,7 @@ describe("FirstVisibleChildLayout", () => {
88
88
 
89
89
  let store = new Store();
90
90
 
91
- const component = createTestRenderer(store, widget);
91
+ const component = await createTestRenderer(store, widget);
92
92
 
93
93
  let tree = component.toJSON();
94
94
  assert.deepEqual(tree, {
@@ -98,7 +98,7 @@ describe("FirstVisibleChildLayout", () => {
98
98
  });
99
99
  });
100
100
 
101
- it("skips pure containers which use parent layouts", () => {
101
+ it("skips pure containers which use parent layouts", async () => {
102
102
  let widget = (
103
103
  <cx>
104
104
  <div layout={FirstVisibleChildLayout}>
@@ -113,7 +113,7 @@ describe("FirstVisibleChildLayout", () => {
113
113
 
114
114
  let store = new Store();
115
115
 
116
- const component = createTestRenderer(store, widget);
116
+ const component = await createTestRenderer(store, widget);
117
117
 
118
118
  let tree = component.toJSON();
119
119
  assert.deepEqual(tree, {
@@ -123,7 +123,7 @@ describe("FirstVisibleChildLayout", () => {
123
123
  });
124
124
  });
125
125
 
126
- it("works with functional components", () => {
126
+ it("works with functional components", async () => {
127
127
  let FC = createFunctionalComponent(({ children }: { children?: any }) => <cx>{children}</cx>);
128
128
 
129
129
  let widget = (
@@ -140,7 +140,7 @@ describe("FirstVisibleChildLayout", () => {
140
140
 
141
141
  let store = new Store();
142
142
 
143
- const component = createTestRenderer(store, widget);
143
+ const component = await createTestRenderer(store, widget);
144
144
 
145
145
  let tree = component.toJSON();
146
146
  assert.deepEqual(tree, {
@@ -150,7 +150,7 @@ describe("FirstVisibleChildLayout", () => {
150
150
  });
151
151
  });
152
152
 
153
- it("properly destroys invisible items", () => {
153
+ it("properly destroys invisible items", async () => {
154
154
  let destroyList: number[] = [];
155
155
  let widget = (
156
156
  <cx>
@@ -166,29 +166,41 @@ describe("FirstVisibleChildLayout", () => {
166
166
 
167
167
  let store = new Store();
168
168
 
169
- const component = createTestRenderer(store, widget);
169
+ const component = await createTestRenderer(store, widget);
170
170
 
171
- store.set("index", 0);
171
+ await act(async () => {
172
+ store.set("index", 0);
173
+ });
172
174
  component.toJSON();
173
175
  assert.deepEqual(destroyList, []);
174
176
 
175
- store.set("index", 3);
177
+ await act(async () => {
178
+ store.set("index", 3);
179
+ });
176
180
  component.toJSON();
177
181
  assert.deepEqual(destroyList, [0]);
178
182
 
179
- store.set("index", 1);
183
+ await act(async () => {
184
+ store.set("index", 1);
185
+ });
180
186
  component.toJSON();
181
187
  assert.deepEqual(destroyList, [0, 3]);
182
188
 
183
- store.set("index", 4);
189
+ await act(async () => {
190
+ store.set("index", 4);
191
+ });
184
192
  component.toJSON();
185
193
  assert.deepEqual(destroyList, [0, 3, 1]);
186
194
 
187
- store.set("index", 0);
195
+ await act(async () => {
196
+ store.set("index", 0);
197
+ });
188
198
  component.toJSON();
189
199
  assert.deepEqual(destroyList, [0, 3, 1, 4]);
190
200
 
191
- store.set("index", -1);
201
+ await act(async () => {
202
+ store.set("index", -1);
203
+ });
192
204
  component.toJSON();
193
205
  assert.deepEqual(destroyList, [0, 3, 1, 4, 0]);
194
206
  });
@@ -1,87 +1,87 @@
1
- import { Selection, SelectionOptions } from "./Selection";
2
- import { View } from "../../data/View";
3
- import { isAccessorChain } from "../../data/createAccessorModelProxy";
4
- import { Binding } from "../Prop";
5
-
6
- export interface PropertySelectionConfig {
7
- /** Name of the field used to indicate selection. Default is `selected`. */
8
- selectedField?: string;
9
-
10
- /** Set to `true` to allow multiple selection. */
11
- multiple?: boolean;
12
-
13
- /** Name of the field used as a key. */
14
- keyField?: string;
15
-
16
- /** Record binding. */
17
- record?: Binding;
18
-
19
- /** Records binding. */
20
- records?: Binding;
21
-
22
- /** Index binding. */
23
- index?: Binding;
24
-
25
- /** Binding path for selection state. */
26
- bind?: string;
27
- }
28
-
29
- export class PropertySelection extends Selection {
30
- declare records: any;
31
- declare selectedField: string;
32
-
33
- constructor(config?: PropertySelectionConfig) {
34
- super(config);
35
- }
36
-
37
- selectMultiple(store: View, records: any[], indexes: any[], { toggle, add }: SelectionOptions = {}): any {
38
- if (this.toggle) toggle = true;
39
-
40
- if (!this.records) return false;
41
-
42
- let path = isAccessorChain(this.records) ? this.records.toString() : this.records.bind;
43
- if (!path) return false;
44
-
45
- let array = store.get(path);
46
- let newArray = [...array];
47
- let dirty = false;
48
-
49
- if (!toggle && !add) {
50
- newArray.forEach((r, i) => {
51
- if (r[this.selectedField]) {
52
- let nr = Object.assign({}, r);
53
- nr[this.selectedField] = false;
54
- newArray[i] = nr;
55
- dirty = true;
56
- }
57
- });
58
- }
59
-
60
- records.forEach((record, i) => {
61
- let index = indexes[i];
62
- let rec = newArray[index];
63
- if (array[index] !== record) throw new Error("Stale data.");
64
-
65
- let value = rec[this.selectedField];
66
- let newValue = add ? true : toggle ? !value : true;
67
-
68
- if (value == newValue) return;
69
-
70
- let newRec = Object.assign({}, rec);
71
- newRec[this.selectedField] = newValue;
72
- newArray[index] = newRec;
73
- dirty = true;
74
- });
75
-
76
- if (dirty) store.set(path, newArray);
77
- }
78
-
79
- isSelected(store: View, record: any, index: any): boolean {
80
- return record && record[this.selectedField!];
81
- }
82
- }
83
-
84
- PropertySelection.prototype.selectedField = "selected";
85
- PropertySelection.prototype.multiple = false;
86
-
87
- (Selection as any).alias("property", PropertySelection);
1
+ import { Selection, SelectionOptions } from "./Selection";
2
+ import { View } from "../../data/View";
3
+ import { isAccessorChain } from "../../data/createAccessorModelProxy";
4
+ import { Binding } from "../Prop";
5
+
6
+ export interface PropertySelectionConfig {
7
+ /** Name of the field used to indicate selection. Default is `selected`. */
8
+ selectedField?: string;
9
+
10
+ /** Set to `true` to allow multiple selection. */
11
+ multiple?: boolean;
12
+
13
+ /** Name of the field used as a key. */
14
+ keyField?: string;
15
+
16
+ /** Record binding. */
17
+ record?: Binding;
18
+
19
+ /** Records binding. */
20
+ records?: Binding;
21
+
22
+ /** Index binding. */
23
+ index?: Binding;
24
+
25
+ /** Binding path for selection state. */
26
+ bind?: string;
27
+ }
28
+
29
+ export class PropertySelection extends Selection {
30
+ declare records: any;
31
+ declare selectedField: string;
32
+
33
+ constructor(config?: PropertySelectionConfig) {
34
+ super(config);
35
+ }
36
+
37
+ selectMultiple(store: View, records: any[], indexes: any[], { toggle, add }: SelectionOptions = {}): any {
38
+ if (this.toggle) toggle = true;
39
+
40
+ if (!this.records) return false;
41
+
42
+ let path = isAccessorChain(this.records) ? this.records.toString() : this.records.bind;
43
+ if (!path) return false;
44
+
45
+ let array = store.get(path);
46
+ let newArray = [...array];
47
+ let dirty = false;
48
+
49
+ if (!toggle && !add) {
50
+ newArray.forEach((r, i) => {
51
+ if (r[this.selectedField]) {
52
+ let nr = Object.assign({}, r);
53
+ nr[this.selectedField] = false;
54
+ newArray[i] = nr;
55
+ dirty = true;
56
+ }
57
+ });
58
+ }
59
+
60
+ records.forEach((record, i) => {
61
+ let index = indexes[i];
62
+ let rec = newArray[index];
63
+ if (array[index] !== record) throw new Error("Stale data.");
64
+
65
+ let value = rec[this.selectedField];
66
+ let newValue = add ? true : toggle ? !value : true;
67
+
68
+ if (value == newValue) return;
69
+
70
+ let newRec = Object.assign({}, rec);
71
+ newRec[this.selectedField] = newValue;
72
+ newArray[index] = newRec;
73
+ dirty = true;
74
+ });
75
+
76
+ if (dirty) store.set(path, newArray);
77
+ }
78
+
79
+ isSelected(store: View, record: any, index: any): boolean {
80
+ return record && record[this.selectedField!];
81
+ }
82
+ }
83
+
84
+ PropertySelection.prototype.selectedField = "selected";
85
+ PropertySelection.prototype.multiple = false;
86
+
87
+ (Selection as any).alias("property", PropertySelection);
@@ -211,6 +211,36 @@ describe("Component.create", function () {
211
211
  });
212
212
  });
213
213
 
214
+ describe("type in second argument (more)", function () {
215
+ it("should create instance of type specified in second argument", function () {
216
+ const result = TestWidget.create({ text: "hello" }, { type: TestButton });
217
+ assert.ok(result instanceof TestButton);
218
+ assert.equal(result.text, "hello");
219
+ });
220
+
221
+ it("should create instance of $type specified in second argument", function () {
222
+ const result = TestWidget.create({ text: "world" }, { $type: TestButton });
223
+ assert.ok(result instanceof TestButton);
224
+ assert.equal(result.text, "world");
225
+ });
226
+
227
+ it("should work when first argument is an array and second has type", function () {
228
+ const results = Component.create([{ text: "A" }, { text: "B" }], { type: TestButton });
229
+ assert.equal(results.length, 2);
230
+ assert.ok(results[0] instanceof TestButton);
231
+ assert.ok(results[1] instanceof TestButton);
232
+ assert.equal(results[0].text, "A");
233
+ assert.equal(results[1].text, "B");
234
+ });
235
+
236
+ it("should work when type is passed as first arg with array config and type in more", function () {
237
+ const results = Component.create(TestWidget, [{ text: "X" }], { type: TestButton });
238
+ assert.equal(results.length, 1);
239
+ assert.ok(results[0] instanceof TestButton);
240
+ assert.equal(results[0].text, "X");
241
+ });
242
+ });
243
+
214
244
  describe("heterogeneous array with type property", function () {
215
245
  it("creates array of different component types", function () {
216
246
  const results = Component.create([