cx 22.4.1 → 22.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data.js +29 -9
- package/dist/manifest.js +495 -495
- package/dist/util.js +15 -9
- package/dist/widgets.js +39 -13
- package/package.json +1 -1
- package/src/core.d.ts +2 -0
- package/src/data/comparer.spec.js +28 -28
- package/src/data/createAccessorModelProxy.js +29 -7
- package/src/data/createAccessorModelProxy.spec.tsx +16 -2
- package/src/ui/Controller.d.ts +38 -1
- package/src/ui/Repeater.d.ts +3 -0
- package/src/ui/layout/Content.d.ts +7 -4
- package/src/util/isTouchEvent.js +33 -21
- package/src/util/scrollElementIntoView.d.ts +2 -1
- package/src/util/scrollElementIntoView.js +7 -32
- package/src/widgets/DocumentTitle.d.ts +2 -1
- package/src/widgets/List.d.ts +4 -1
- package/src/widgets/List.js +16 -14
- package/src/widgets/form/Calendar.d.ts +4 -1
- package/src/widgets/form/Calendar.js +23 -23
- package/src/widgets/form/TextField.js +3 -4
- package/src/widgets/grid/Grid.js +13 -4
- package/src/widgets/grid/GridRow.js +3 -3
- package/src/widgets/nav/Link.d.ts +5 -1
- package/src/widgets/nav/LinkButton.d.ts +1 -1
package/dist/util.js
CHANGED
|
@@ -660,7 +660,7 @@ function getScrollerBoundingClientRect(scrollEl, topLevel) {
|
|
|
660
660
|
return topLevel ? getTopLevelBoundingClientRect(scrollEl) : scrollEl.getBoundingClientRect();
|
|
661
661
|
}
|
|
662
662
|
|
|
663
|
-
function scrollElementIntoView(el, vertical, horizontal, inflate) {
|
|
663
|
+
function scrollElementIntoView(el, vertical, horizontal, inflate, scrollContainer) {
|
|
664
664
|
if (vertical === void 0) {
|
|
665
665
|
vertical = true;
|
|
666
666
|
}
|
|
@@ -673,8 +673,12 @@ function scrollElementIntoView(el, vertical, horizontal, inflate) {
|
|
|
673
673
|
inflate = 0;
|
|
674
674
|
}
|
|
675
675
|
|
|
676
|
+
if (scrollContainer === void 0) {
|
|
677
|
+
scrollContainer = null;
|
|
678
|
+
}
|
|
679
|
+
|
|
676
680
|
if (horizontal) {
|
|
677
|
-
var parentEl = findScrollableParent(el, true);
|
|
681
|
+
var parentEl = scrollContainer || findScrollableParent(el, true);
|
|
678
682
|
|
|
679
683
|
if (parentEl) {
|
|
680
684
|
var pr = getScrollerBoundingClientRect(parentEl);
|
|
@@ -688,7 +692,7 @@ function scrollElementIntoView(el, vertical, horizontal, inflate) {
|
|
|
688
692
|
}
|
|
689
693
|
|
|
690
694
|
if (vertical) {
|
|
691
|
-
var _parentEl = findScrollableParent(el);
|
|
695
|
+
var _parentEl = scrollContainer || findScrollableParent(el);
|
|
692
696
|
|
|
693
697
|
if (_parentEl) {
|
|
694
698
|
var _pr = getScrollerBoundingClientRect(_parentEl);
|
|
@@ -1200,15 +1204,17 @@ var lastTouchEvent = 0;
|
|
|
1200
1204
|
var isTouchDetectionEnabled = false;
|
|
1201
1205
|
function enableTouchEventDetection() {
|
|
1202
1206
|
if (isTouchDevice() && !isTouchDetectionEnabled) {
|
|
1203
|
-
var options;
|
|
1207
|
+
var options = true; //capture
|
|
1208
|
+
|
|
1204
1209
|
if (browserSupportsPassiveEventHandlers())
|
|
1205
1210
|
options = {
|
|
1206
|
-
passive: true
|
|
1211
|
+
passive: true,
|
|
1212
|
+
capture: true
|
|
1207
1213
|
};
|
|
1208
1214
|
document.addEventListener(
|
|
1209
1215
|
"touchstart",
|
|
1210
1216
|
function() {
|
|
1211
|
-
lastTouchEvent =
|
|
1217
|
+
lastTouchEvent = Date.now();
|
|
1212
1218
|
},
|
|
1213
1219
|
options
|
|
1214
1220
|
);
|
|
@@ -1216,14 +1222,14 @@ function enableTouchEventDetection() {
|
|
|
1216
1222
|
"touchmove",
|
|
1217
1223
|
function() {
|
|
1218
1224
|
//console.log('TOUCHMOVE');
|
|
1219
|
-
lastTouchEvent =
|
|
1225
|
+
lastTouchEvent = Date.now();
|
|
1220
1226
|
},
|
|
1221
1227
|
options
|
|
1222
1228
|
);
|
|
1223
1229
|
document.addEventListener(
|
|
1224
1230
|
"touchend",
|
|
1225
1231
|
function() {
|
|
1226
|
-
lastTouchEvent =
|
|
1232
|
+
lastTouchEvent = Date.now(); //console.log('TOUCHEND');
|
|
1227
1233
|
},
|
|
1228
1234
|
options
|
|
1229
1235
|
);
|
|
@@ -1231,7 +1237,7 @@ function enableTouchEventDetection() {
|
|
|
1231
1237
|
}
|
|
1232
1238
|
}
|
|
1233
1239
|
function isTouchEvent() {
|
|
1234
|
-
return isTouchDevice() && (!isTouchDetectionEnabled ||
|
|
1240
|
+
return isTouchDevice() && (!isTouchDetectionEnabled || Date.now() - lastTouchEvent < 1000);
|
|
1235
1241
|
} //enable touch event detection if there is no performance penalty on scrolling
|
|
1236
1242
|
|
|
1237
1243
|
if (isTouchDevice() && browserSupportsPassiveEventHandlers()) enableTouchEventDetection();
|
package/dist/widgets.js
CHANGED
|
@@ -1810,7 +1810,7 @@ var ListComponent = /*#__PURE__*/ (function(_VDOM$Component) {
|
|
|
1810
1810
|
var firstSelectedRow = this.el.querySelector(selectedRowSelector);
|
|
1811
1811
|
|
|
1812
1812
|
if (firstSelectedRow != this.selectedEl) {
|
|
1813
|
-
if (firstSelectedRow) scrollElementIntoView(firstSelectedRow);
|
|
1813
|
+
if (firstSelectedRow) scrollElementIntoView(firstSelectedRow, true, false, 0, this.el);
|
|
1814
1814
|
this.selectedEl = firstSelectedRow;
|
|
1815
1815
|
}
|
|
1816
1816
|
};
|
|
@@ -8258,7 +8258,7 @@ var Input = /*#__PURE__*/ (function(_VDOM$Component) {
|
|
|
8258
8258
|
immediate: immediate
|
|
8259
8259
|
})
|
|
8260
8260
|
) {
|
|
8261
|
-
if (text != this.
|
|
8261
|
+
if (text != this.input.value && immediate) this.input.value = text;
|
|
8262
8262
|
} else {
|
|
8263
8263
|
if (value)
|
|
8264
8264
|
instance.setState({
|
|
@@ -9355,12 +9355,23 @@ var CalendarCmp = /*#__PURE__*/ (function(_VDOM$Component) {
|
|
|
9355
9355
|
_proto2.getPage = function getPage(refDate) {
|
|
9356
9356
|
refDate = monthStart(refDate); //make a copy
|
|
9357
9357
|
|
|
9358
|
+
var startWithMonday = this.props.instance.widget.startWithMonday;
|
|
9359
|
+
var startDay = startWithMonday ? 1 : 0;
|
|
9358
9360
|
var startDate = new Date(refDate);
|
|
9359
|
-
|
|
9361
|
+
|
|
9362
|
+
while (startDate.getDay() != startDay) {
|
|
9363
|
+
startDate.setDate(startDate.getDate() - 1);
|
|
9364
|
+
}
|
|
9365
|
+
|
|
9360
9366
|
var endDate = new Date(refDate);
|
|
9361
9367
|
endDate.setMonth(refDate.getMonth() + 1);
|
|
9362
9368
|
endDate.setDate(endDate.getDate() - 1);
|
|
9363
|
-
|
|
9369
|
+
var endDay = startWithMonday ? 0 : 6;
|
|
9370
|
+
|
|
9371
|
+
while (endDate.getDay() != endDay) {
|
|
9372
|
+
endDate.setDate(endDate.getDate() + 1);
|
|
9373
|
+
}
|
|
9374
|
+
|
|
9364
9375
|
return {
|
|
9365
9376
|
refDate: refDate,
|
|
9366
9377
|
startDate: startDate,
|
|
@@ -9574,16 +9585,19 @@ var CalendarCmp = /*#__PURE__*/ (function(_VDOM$Component) {
|
|
|
9574
9585
|
baseClass = widget.baseClass,
|
|
9575
9586
|
disabledDaysOfWeek = widget.disabledDaysOfWeek,
|
|
9576
9587
|
startWithMonday = widget.startWithMonday;
|
|
9577
|
-
|
|
9588
|
+
|
|
9589
|
+
var _this$getPage = this.getPage(this.state.refDate),
|
|
9590
|
+
refDate = _this$getPage.refDate,
|
|
9591
|
+
startDate = _this$getPage.startDate,
|
|
9592
|
+
endDate = _this$getPage.endDate;
|
|
9593
|
+
|
|
9578
9594
|
var month = refDate.getMonth();
|
|
9579
9595
|
var year = refDate.getFullYear();
|
|
9580
|
-
var startDate = new Date(year, month, 1);
|
|
9581
|
-
startDate.setDate(1 - startDate.getDay() + (startWithMonday ? 1 : 0));
|
|
9582
9596
|
var weeks = [];
|
|
9583
9597
|
var date = startDate;
|
|
9584
9598
|
var today = zeroTime(new Date());
|
|
9585
9599
|
|
|
9586
|
-
while (date
|
|
9600
|
+
while (date >= startDate && date <= endDate) {
|
|
9587
9601
|
var days = [];
|
|
9588
9602
|
|
|
9589
9603
|
for (var i = 0; i < 7; i++) {
|
|
@@ -17210,7 +17224,7 @@ var GridRowComponent = /*#__PURE__*/ (function(_VDOM$Component) {
|
|
|
17210
17224
|
e.preventDefault();
|
|
17211
17225
|
e.stopPropagation(); //close context menu
|
|
17212
17226
|
|
|
17213
|
-
unfocusElement(e.target);
|
|
17227
|
+
unfocusElement(e.target, false);
|
|
17214
17228
|
}
|
|
17215
17229
|
}
|
|
17216
17230
|
|
|
@@ -18373,7 +18387,8 @@ var Grid = /*#__PURE__*/ (function(_Widget) {
|
|
|
18373
18387
|
baseClass = this.baseClass;
|
|
18374
18388
|
var data = store.getData();
|
|
18375
18389
|
var skip = 0;
|
|
18376
|
-
var header = instance.header
|
|
18390
|
+
var header = instance.header,
|
|
18391
|
+
state = instance.state;
|
|
18377
18392
|
var rowStyle = {};
|
|
18378
18393
|
var lines = [];
|
|
18379
18394
|
header.children.forEach(function(line, lineIndex) {
|
|
@@ -18383,7 +18398,7 @@ var Grid = /*#__PURE__*/ (function(_Widget) {
|
|
|
18383
18398
|
if (Boolean(ci.data.fixed) != fixedColumns) return null;
|
|
18384
18399
|
var v,
|
|
18385
18400
|
c = ci.widget,
|
|
18386
|
-
colSpan,
|
|
18401
|
+
colSpan = 1,
|
|
18387
18402
|
pad,
|
|
18388
18403
|
cls = "",
|
|
18389
18404
|
style = null;
|
|
@@ -18419,7 +18434,18 @@ var Grid = /*#__PURE__*/ (function(_Widget) {
|
|
|
18419
18434
|
|
|
18420
18435
|
if (cls) cls += " ";
|
|
18421
18436
|
if (c.align) cls += CSS.state("aligned-" + c.align);
|
|
18422
|
-
if (pad !== false) cls += (cls ? " " : "") + CSS.state("pad");
|
|
18437
|
+
if (pad !== false) cls += (cls ? " " : "") + CSS.state("pad"); // apply column width to footers too, but only if colSpan == 1,
|
|
18438
|
+
// otherwise set 1px so that the footer is not participating in the layout
|
|
18439
|
+
|
|
18440
|
+
var maxWidth = 1;
|
|
18441
|
+
if (colSpan == 1) maxWidth = state.colWidth[c.uniqueColumnId];
|
|
18442
|
+
style = _objectSpread2(
|
|
18443
|
+
_objectSpread2({}, style),
|
|
18444
|
+
{},
|
|
18445
|
+
{
|
|
18446
|
+
maxWidth: maxWidth
|
|
18447
|
+
}
|
|
18448
|
+
);
|
|
18423
18449
|
return /*#__PURE__*/ jsx(
|
|
18424
18450
|
"td",
|
|
18425
18451
|
{
|
|
@@ -20128,7 +20154,7 @@ var GridComponent = /*#__PURE__*/ (function(_VDOM$Component) {
|
|
|
20128
20154
|
if (!futureState.cellEdit && wasCellEditing) {
|
|
20129
20155
|
//If cell editing is in progress, moving the cursor may cause that the cell editor is unmounted before
|
|
20130
20156
|
//the blur event which may cause data loss for components which do not have reactOn=change set, e.g. NumberField.
|
|
20131
|
-
unfocusElement();
|
|
20157
|
+
unfocusElement(null, false);
|
|
20132
20158
|
|
|
20133
20159
|
var record = _this11.getRecordAt(prevState.cursor);
|
|
20134
20160
|
|
package/package.json
CHANGED
package/src/core.d.ts
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
import {sorter} from
|
|
2
|
-
import assert from
|
|
1
|
+
import { sorter } from "./comparer";
|
|
2
|
+
import assert from "assert";
|
|
3
3
|
|
|
4
|
-
describe(
|
|
5
|
-
describe(
|
|
6
|
-
it(
|
|
4
|
+
describe("comparer", function () {
|
|
5
|
+
describe("sorter", function () {
|
|
6
|
+
it("orders by numeric values ASC", function () {
|
|
7
7
|
let records = [
|
|
8
|
-
{value: 3, id: 1},
|
|
9
|
-
{value: -1, id: 2},
|
|
10
|
-
{value: 2, id: 3},
|
|
11
|
-
{value: null, id: 4},
|
|
12
|
-
{value: null, id: 5},
|
|
8
|
+
{ value: 3, id: 1 },
|
|
9
|
+
{ value: -1, id: 2 },
|
|
10
|
+
{ value: 2, id: 3 },
|
|
11
|
+
{ value: null, id: 4 },
|
|
12
|
+
{ value: null, id: 5 },
|
|
13
13
|
];
|
|
14
14
|
|
|
15
|
-
let sort = sorter([{value: {bind:
|
|
15
|
+
let sort = sorter([{ value: { bind: "value" }, direction: "ASC" }]);
|
|
16
16
|
|
|
17
17
|
let sorted = sort(records);
|
|
18
18
|
|
|
19
|
-
assert.equal(sorted[0].value,
|
|
20
|
-
assert.equal(sorted[1].value,
|
|
21
|
-
assert.equal(sorted[2].value,
|
|
22
|
-
assert.equal(sorted[3].value,
|
|
23
|
-
assert.equal(sorted[4].value,
|
|
19
|
+
assert.equal(sorted[0].value, -1);
|
|
20
|
+
assert.equal(sorted[1].value, 2);
|
|
21
|
+
assert.equal(sorted[2].value, 3);
|
|
22
|
+
assert.equal(sorted[3].value, null);
|
|
23
|
+
assert.equal(sorted[4].value, null);
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
it(
|
|
26
|
+
it("orders by numeric values DESC", function () {
|
|
27
27
|
let records = [
|
|
28
|
-
{value: 3, id: 1},
|
|
29
|
-
{value: 1, id: 2},
|
|
30
|
-
{value: -2, id: 3},
|
|
31
|
-
{value: null, id: 4},
|
|
32
|
-
{value: null, id: 5},
|
|
28
|
+
{ value: 3, id: 1 },
|
|
29
|
+
{ value: 1, id: 2 },
|
|
30
|
+
{ value: -2, id: 3 },
|
|
31
|
+
{ value: null, id: 4 },
|
|
32
|
+
{ value: null, id: 5 },
|
|
33
33
|
];
|
|
34
34
|
|
|
35
|
-
let sort = sorter([{value: {bind:
|
|
35
|
+
let sort = sorter([{ value: { bind: "value" }, direction: "DESC" }]);
|
|
36
36
|
|
|
37
37
|
let sorted = sort(records);
|
|
38
38
|
|
|
@@ -43,14 +43,14 @@ describe('comparer', function() {
|
|
|
43
43
|
assert.equal(sorted[4].value, null);
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
it(
|
|
46
|
+
it("supports field", function () {
|
|
47
47
|
let records = [
|
|
48
|
-
{value: 3, id: 1},
|
|
49
|
-
{value: 1, id: 2},
|
|
50
|
-
{value: 2, id: 3}
|
|
48
|
+
{ value: 3, id: 1 },
|
|
49
|
+
{ value: 1, id: 2 },
|
|
50
|
+
{ value: 2, id: 3 },
|
|
51
51
|
];
|
|
52
52
|
|
|
53
|
-
let sort = sorter([{field:
|
|
53
|
+
let sort = sorter([{ field: "value", direction: "ASC" }]);
|
|
54
54
|
let sorted = sort(records);
|
|
55
55
|
assert.equal(sorted[0].value, 1);
|
|
56
56
|
assert.equal(sorted[1].value, 2);
|
|
@@ -1,21 +1,43 @@
|
|
|
1
|
+
const emptyFn = () => {};
|
|
2
|
+
|
|
1
3
|
export function createAccessorModelProxy(chain = "") {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
let lastOp = null;
|
|
5
|
+
let lastName = null;
|
|
6
|
+
|
|
7
|
+
const proxy = new Proxy(emptyFn, {
|
|
8
|
+
get: (_, name) => {
|
|
9
|
+
if (typeof name !== "string") return proxy;
|
|
10
|
+
|
|
11
|
+
switch (name) {
|
|
12
|
+
case "isAccessorChain":
|
|
13
|
+
return true;
|
|
14
|
+
|
|
15
|
+
case "toString":
|
|
16
|
+
case "valueOf":
|
|
17
|
+
case "nameOf":
|
|
18
|
+
lastOp = name;
|
|
19
|
+
return proxy;
|
|
20
|
+
}
|
|
7
21
|
|
|
8
22
|
let newChain = chain;
|
|
9
23
|
if (newChain.length > 0) newChain += ".";
|
|
10
24
|
newChain += name;
|
|
25
|
+
lastName = name;
|
|
11
26
|
return createAccessorModelProxy(newChain);
|
|
12
27
|
},
|
|
13
28
|
|
|
14
29
|
apply() {
|
|
15
|
-
|
|
30
|
+
switch (lastOp) {
|
|
31
|
+
case "nameOf":
|
|
32
|
+
if (lastName != null) return lastName;
|
|
33
|
+
const lastDotIndex = chain.lastIndexOf(".");
|
|
34
|
+
return lastDotIndex > 0 ? chain.substring(lastDotIndex + 1) : chain;
|
|
35
|
+
|
|
36
|
+
default:
|
|
37
|
+
return chain;
|
|
38
|
+
}
|
|
16
39
|
},
|
|
17
40
|
});
|
|
18
|
-
proxy.isAccessorChain = true;
|
|
19
41
|
return proxy;
|
|
20
42
|
}
|
|
21
43
|
|
|
@@ -5,19 +5,33 @@ interface Model {
|
|
|
5
5
|
firstName: string;
|
|
6
6
|
address: {
|
|
7
7
|
city: string;
|
|
8
|
+
streetNumber: number;
|
|
8
9
|
};
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
describe("createAccessorModelProxy", () => {
|
|
12
13
|
it("generates correct paths", () => {
|
|
13
|
-
|
|
14
|
+
let model = createAccessorModelProxy<Model>();
|
|
14
15
|
assert.strictEqual(model.firstName.toString(), "firstName");
|
|
15
16
|
assert.strictEqual(model.address.toString(), "address");
|
|
16
17
|
assert.strictEqual(model.address.city.toString(), "address.city");
|
|
17
18
|
});
|
|
18
19
|
|
|
19
20
|
it("can be used in string templates", () => {
|
|
20
|
-
|
|
21
|
+
let model = createAccessorModelProxy<Model>();
|
|
21
22
|
assert.strictEqual("address.city", `${model.address.city}`);
|
|
23
|
+
assert.strictEqual("address.city", "" + model.address.city);
|
|
24
|
+
assert.strictEqual("address.city.suffix", model.address.city + ".suffix");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("nameOf returns name of the last prop ", () => {
|
|
28
|
+
let model = createAccessorModelProxy<Model>();
|
|
29
|
+
assert.strictEqual(model.firstName.nameOf(), "firstName");
|
|
30
|
+
assert.strictEqual(model.address.nameOf(), "address");
|
|
31
|
+
assert.strictEqual(model.address.city.nameOf(), "city");
|
|
32
|
+
|
|
33
|
+
let { streetNumber, city } = model.address;
|
|
34
|
+
assert.strictEqual(streetNumber.nameOf(), "streetNumber");
|
|
35
|
+
assert.strictEqual(city.nameOf(), "city");
|
|
22
36
|
});
|
|
23
37
|
});
|
package/src/ui/Controller.d.ts
CHANGED
|
@@ -18,6 +18,26 @@ export class Controller<D = any> {
|
|
|
18
18
|
store: View<D>;
|
|
19
19
|
widget: any;
|
|
20
20
|
|
|
21
|
+
addTrigger<V1>(name: string, args: [Cx.AccessorChain<V1>], callback: (v1: V1) => void, autoRun?: boolean): void;
|
|
22
|
+
addTrigger<V1, V2>(
|
|
23
|
+
name: string,
|
|
24
|
+
args: [Cx.AccessorChain<V1>, Cx.AccessorChain<V2>],
|
|
25
|
+
callback: (v1: V1, v2: V2) => void,
|
|
26
|
+
autoRun?: boolean
|
|
27
|
+
): void;
|
|
28
|
+
addTrigger<V1, V2, V3>(
|
|
29
|
+
name: string,
|
|
30
|
+
args: [Cx.AccessorChain<V1>, Cx.AccessorChain<V2>, Cx.AccessorChain<V3>],
|
|
31
|
+
callback: (v1: V1, v2: V2, v3: V3) => void,
|
|
32
|
+
autoRun?: boolean
|
|
33
|
+
): void;
|
|
34
|
+
addTrigger<V1, V2, V3, V4>(
|
|
35
|
+
name: string,
|
|
36
|
+
args: [Cx.AccessorChain<V1>, Cx.AccessorChain<V2>, Cx.AccessorChain<V3>, Cx.AccessorChain<V4>],
|
|
37
|
+
callback: (v1: V1, v2: V2, v3: V3, v4: V4) => void,
|
|
38
|
+
autoRun?: boolean
|
|
39
|
+
): void;
|
|
40
|
+
|
|
21
41
|
addTrigger(
|
|
22
42
|
name: string,
|
|
23
43
|
args: (string | Cx.AccessorChain<any>)[],
|
|
@@ -25,7 +45,24 @@ export class Controller<D = any> {
|
|
|
25
45
|
autoRun?: boolean
|
|
26
46
|
): void;
|
|
27
47
|
|
|
28
|
-
addComputable(
|
|
48
|
+
addComputable<V1, R>(path: Cx.AccessorChain<R>, args: [Cx.AccessorChain<V1>], callback: (v1: V1) => R): void;
|
|
49
|
+
addComputable<V1, V2, R>(
|
|
50
|
+
path: Cx.AccessorChain<R>,
|
|
51
|
+
args: [Cx.AccessorChain<V1>, Cx.AccessorChain<V2>],
|
|
52
|
+
callback: (v1: V1, v2: V2) => R
|
|
53
|
+
): void;
|
|
54
|
+
addComputable<V1, V2, V3, R>(
|
|
55
|
+
path: Cx.AccessorChain<R>,
|
|
56
|
+
args: [Cx.AccessorChain<V1>, Cx.AccessorChain<V2>, Cx.AccessorChain<V3>],
|
|
57
|
+
callback: (v1: V1, v2: V2, v3: V3) => R
|
|
58
|
+
): void;
|
|
59
|
+
addComputable<V1, V2, V3, V4, R>(
|
|
60
|
+
path: Cx.AccessorChain<R>,
|
|
61
|
+
args: [Cx.AccessorChain<V1>, Cx.AccessorChain<V2>, Cx.AccessorChain<V3>, Cx.AccessorChain<V4>],
|
|
62
|
+
callback: (v1: V1, v2: V2, v3: V3, v4: V4) => R
|
|
63
|
+
): void;
|
|
64
|
+
|
|
65
|
+
addComputable(path: string, args: (string | Cx.AccessorChain<any>)[], callback: (...args) => any): void;
|
|
29
66
|
|
|
30
67
|
removeTrigger(name: string): void;
|
|
31
68
|
|
package/src/ui/Repeater.d.ts
CHANGED
|
@@ -41,6 +41,9 @@ interface RepeaterProps extends PureContainerProps {
|
|
|
41
41
|
|
|
42
42
|
/** Options for data sorting. See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator */
|
|
43
43
|
sortOptions?: CollatorOptions;
|
|
44
|
+
|
|
45
|
+
/** A field used to get the unique identifier of the record. Setting keyField improves performance on sort operations as the widget is able to movement of records inside the collection. */
|
|
46
|
+
keyField: StringProp;
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
export class Repeater extends Widget<RepeaterProps> {}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import * as Cx from
|
|
1
|
+
import * as Cx from "../../core";
|
|
2
2
|
|
|
3
3
|
interface ContentProps extends Cx.PureContainerProps {
|
|
4
|
+
/** Placeholder name where the content is rendered. */
|
|
5
|
+
name?: string;
|
|
4
6
|
|
|
5
|
-
name
|
|
6
|
-
|
|
7
|
-
isContent?: boolean
|
|
7
|
+
/** Placeholder name where the content is rendered. */
|
|
8
|
+
for?: string;
|
|
8
9
|
|
|
10
|
+
/** Placeholder name where the content is rendered. */
|
|
11
|
+
putInto?: string;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
export class Content extends Cx.Widget<ContentProps> {}
|
package/src/util/isTouchEvent.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { browserSupportsPassiveEventHandlers } from
|
|
2
|
-
import { isTouchDevice } from
|
|
1
|
+
import { browserSupportsPassiveEventHandlers } from "./browserSupportsPassiveEventHandlers";
|
|
2
|
+
import { isTouchDevice } from "./isTouchDevice";
|
|
3
3
|
|
|
4
4
|
// This is primarily used for tooltips which behave differently on touch.
|
|
5
5
|
// For example, tooltips are commonly toggled on touch or disabled completely.
|
|
@@ -15,38 +15,50 @@ let isTouchDetectionEnabled = false;
|
|
|
15
15
|
|
|
16
16
|
export function enableTouchEventDetection() {
|
|
17
17
|
if (isTouchDevice() && !isTouchDetectionEnabled) {
|
|
18
|
-
let options;
|
|
18
|
+
let options = true; //capture
|
|
19
19
|
|
|
20
20
|
if (browserSupportsPassiveEventHandlers())
|
|
21
21
|
options = {
|
|
22
|
-
passive: true
|
|
22
|
+
passive: true,
|
|
23
|
+
capture: true,
|
|
23
24
|
};
|
|
24
25
|
|
|
25
|
-
document.addEventListener(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
document.addEventListener(
|
|
27
|
+
"touchstart",
|
|
28
|
+
() => {
|
|
29
|
+
insideTouchEvent++;
|
|
30
|
+
//console.log('TOUCHSTART');
|
|
31
|
+
lastTouchEvent = Date.now();
|
|
32
|
+
},
|
|
33
|
+
options
|
|
34
|
+
);
|
|
30
35
|
|
|
31
|
-
document.addEventListener(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
document.addEventListener(
|
|
37
|
+
"touchmove",
|
|
38
|
+
() => {
|
|
39
|
+
//console.log('TOUCHMOVE');
|
|
40
|
+
lastTouchEvent = Date.now();
|
|
41
|
+
},
|
|
42
|
+
options
|
|
43
|
+
);
|
|
35
44
|
|
|
36
|
-
document.addEventListener(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
document.addEventListener(
|
|
46
|
+
"touchend",
|
|
47
|
+
() => {
|
|
48
|
+
insideTouchEvent--;
|
|
49
|
+
lastTouchEvent = Date.now();
|
|
50
|
+
//console.log('TOUCHEND');
|
|
51
|
+
},
|
|
52
|
+
options
|
|
53
|
+
);
|
|
41
54
|
|
|
42
55
|
isTouchDetectionEnabled = true;
|
|
43
56
|
}
|
|
44
57
|
}
|
|
45
58
|
|
|
46
59
|
export function isTouchEvent() {
|
|
47
|
-
return isTouchDevice() && (!isTouchDetectionEnabled ||
|
|
60
|
+
return isTouchDevice() && (!isTouchDetectionEnabled || Date.now() - lastTouchEvent < 1000);
|
|
48
61
|
}
|
|
49
62
|
|
|
50
63
|
//enable touch event detection if there is no performance penalty on scrolling
|
|
51
|
-
if (isTouchDevice() && browserSupportsPassiveEventHandlers())
|
|
52
|
-
enableTouchEventDetection();
|
|
64
|
+
if (isTouchDevice() && browserSupportsPassiveEventHandlers()) enableTouchEventDetection();
|
|
@@ -1,59 +1,34 @@
|
|
|
1
1
|
import { findScrollableParent } from "./findScrollableParent";
|
|
2
2
|
import { getScrollerBoundingClientRect } from "./getScrollerBoundingClientRect";
|
|
3
3
|
|
|
4
|
-
export function scrollElementIntoView(
|
|
5
|
-
el,
|
|
6
|
-
vertical = true,
|
|
7
|
-
horizontal = false,
|
|
8
|
-
inflate = 0
|
|
9
|
-
) {
|
|
4
|
+
export function scrollElementIntoView(el, vertical = true, horizontal = false, inflate = 0, scrollContainer = null) {
|
|
10
5
|
if (horizontal) {
|
|
11
|
-
let parentEl = findScrollableParent(el, true);
|
|
6
|
+
let parentEl = scrollContainer || findScrollableParent(el, true);
|
|
12
7
|
if (parentEl) {
|
|
13
8
|
let pr = getScrollerBoundingClientRect(parentEl);
|
|
14
9
|
let er = el.getBoundingClientRect();
|
|
15
10
|
let scrollbarWidth = parentEl.offsetWidth - parentEl.clientWidth;
|
|
16
11
|
|
|
17
12
|
if (er.right + inflate > pr.right - scrollbarWidth)
|
|
18
|
-
parentEl.scrollLeft = Math.max(
|
|
19
|
-
0,
|
|
20
|
-
parentEl.scrollLeft +
|
|
21
|
-
er.right +
|
|
22
|
-
inflate -
|
|
23
|
-
pr.right +
|
|
24
|
-
scrollbarWidth
|
|
25
|
-
);
|
|
13
|
+
parentEl.scrollLeft = Math.max(0, parentEl.scrollLeft + er.right + inflate - pr.right + scrollbarWidth);
|
|
26
14
|
|
|
27
15
|
if (er.left - inflate < pr.left)
|
|
28
|
-
parentEl.scrollLeft = Math.max(
|
|
29
|
-
0,
|
|
30
|
-
parentEl.scrollLeft + er.left - inflate - pr.left
|
|
31
|
-
);
|
|
16
|
+
parentEl.scrollLeft = Math.max(0, parentEl.scrollLeft + er.left - inflate - pr.left);
|
|
32
17
|
}
|
|
33
18
|
}
|
|
34
19
|
|
|
35
20
|
if (vertical) {
|
|
36
|
-
let parentEl = findScrollableParent(el);
|
|
21
|
+
let parentEl = scrollContainer || findScrollableParent(el);
|
|
37
22
|
if (parentEl) {
|
|
38
23
|
let pr = getScrollerBoundingClientRect(parentEl);
|
|
39
24
|
let er = el.getBoundingClientRect();
|
|
40
25
|
let scrollbarHeight = parentEl.offsetHeight - parentEl.clientHeight;
|
|
41
26
|
|
|
42
27
|
if (er.bottom + inflate > pr.bottom - scrollbarHeight)
|
|
43
|
-
parentEl.scrollTop = Math.max(
|
|
44
|
-
0,
|
|
45
|
-
parentEl.scrollTop +
|
|
46
|
-
er.bottom +
|
|
47
|
-
inflate -
|
|
48
|
-
pr.bottom +
|
|
49
|
-
scrollbarHeight
|
|
50
|
-
);
|
|
28
|
+
parentEl.scrollTop = Math.max(0, parentEl.scrollTop + er.bottom + inflate - pr.bottom + scrollbarHeight);
|
|
51
29
|
|
|
52
30
|
if (er.top - inflate < pr.top)
|
|
53
|
-
parentEl.scrollTop = Math.max(
|
|
54
|
-
0,
|
|
55
|
-
parentEl.scrollTop + er.top - inflate - pr.top
|
|
56
|
-
);
|
|
31
|
+
parentEl.scrollTop = Math.max(0, parentEl.scrollTop + er.top - inflate - pr.top);
|
|
57
32
|
}
|
|
58
33
|
}
|
|
59
34
|
}
|
|
@@ -4,7 +4,8 @@ interface DocumentTitleProps extends Cx.WidgetProps {
|
|
|
4
4
|
|
|
5
5
|
value?: Cx.StringProp,
|
|
6
6
|
append?: boolean,
|
|
7
|
-
action?: 'append' | 'replace' | 'prepend'
|
|
7
|
+
action?: 'append' | 'replace' | 'prepend',
|
|
8
|
+
separator?: Cx.StringProp
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export class DocumentTitle extends Cx.Widget<DocumentTitleProps> {}
|
package/src/widgets/List.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as React from "react";
|
|
1
2
|
import {
|
|
2
3
|
BooleanProp,
|
|
3
4
|
ClassProp,
|
|
@@ -11,7 +12,7 @@ import {
|
|
|
11
12
|
StructuredProp,
|
|
12
13
|
StyledContainerProps,
|
|
13
14
|
StyleProp,
|
|
14
|
-
Widget
|
|
15
|
+
Widget
|
|
15
16
|
} from "../core";
|
|
16
17
|
import { Instance } from "./../ui/Instance";
|
|
17
18
|
|
|
@@ -79,6 +80,8 @@ interface ListProps extends StyledContainerProps {
|
|
|
79
80
|
|
|
80
81
|
/** Callback to be invoked when the list is being scrolled. Useful for loading additional items. */
|
|
81
82
|
onScroll?: (event: Event, instance: Instance) => void;
|
|
83
|
+
|
|
84
|
+
onItemClick?: string | ((e: React.SyntheticEvent<any>, instance: Instance) => void);
|
|
82
85
|
}
|
|
83
86
|
|
|
84
87
|
export class List extends Widget<ListProps> {}
|