cx 26.0.13 → 26.0.14
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/widgets/overlay/createHotPromiseWindowFactory.js +0 -1
- package/dist/manifest.js +791 -791
- package/dist/widgets.js +0 -1
- package/package.json +1 -1
- package/src/jsx-runtime.spec.tsx +38 -9
- package/src/util/Format.spec.ts +41 -41
- package/src/widgets/overlay/createHotPromiseWindowFactory.ts +71 -72
package/dist/widgets.js
CHANGED
|
@@ -4542,7 +4542,6 @@ function createHotPromiseWindowFactoryWithProps(module, factory) {
|
|
|
4542
4542
|
let window = Window.create(factory(props)(resolve, reject));
|
|
4543
4543
|
window.overlayWillDismiss = () => {
|
|
4544
4544
|
if (!reloading && unsubscribe) unsubscribe();
|
|
4545
|
-
return false;
|
|
4546
4545
|
};
|
|
4547
4546
|
dismiss = window.open(store);
|
|
4548
4547
|
}
|
package/package.json
CHANGED
package/src/jsx-runtime.spec.tsx
CHANGED
|
@@ -1,7 +1,34 @@
|
|
|
1
1
|
import assert from "assert";
|
|
2
|
-
import { TextField } from "./widgets/form/TextField";
|
|
3
|
-
import { NumberField } from "./widgets/form/NumberField";
|
|
4
2
|
import { Button } from "./widgets/Button";
|
|
3
|
+
import { Widget, WidgetConfig } from "./ui/Widget";
|
|
4
|
+
import { StringProp, NumberProp, BooleanProp } from "./core";
|
|
5
|
+
|
|
6
|
+
// Minimal mock implementations to avoid side effects from importing real widgets
|
|
7
|
+
|
|
8
|
+
interface TextFieldConfig extends WidgetConfig {
|
|
9
|
+
value?: StringProp;
|
|
10
|
+
placeholder?: StringProp;
|
|
11
|
+
disabled?: BooleanProp;
|
|
12
|
+
readOnly?: BooleanProp;
|
|
13
|
+
required?: BooleanProp;
|
|
14
|
+
minLength?: NumberProp;
|
|
15
|
+
maxLength?: NumberProp;
|
|
16
|
+
validationErrorText?: StringProp;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
class TextField extends Widget<TextFieldConfig> {}
|
|
20
|
+
|
|
21
|
+
interface NumberFieldConfig extends WidgetConfig {
|
|
22
|
+
value?: NumberProp;
|
|
23
|
+
placeholder?: StringProp;
|
|
24
|
+
minValue?: NumberProp;
|
|
25
|
+
maxValue?: NumberProp;
|
|
26
|
+
format?: StringProp;
|
|
27
|
+
disabled?: BooleanProp;
|
|
28
|
+
increment?: NumberProp;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
class NumberField extends Widget<NumberFieldConfig> {}
|
|
5
32
|
import { Checkbox } from "./widgets/form/Checkbox";
|
|
6
33
|
import { bind } from "./ui/bind";
|
|
7
34
|
import { expr } from "./ui/expr";
|
|
@@ -343,13 +370,15 @@ describe("jsx-runtime type inference", () => {
|
|
|
343
370
|
optional?: boolean;
|
|
344
371
|
}
|
|
345
372
|
|
|
346
|
-
const ComponentWithRequiredProps = createFunctionalComponent<RequiredPropsConfig>(
|
|
347
|
-
|
|
348
|
-
<
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
373
|
+
const ComponentWithRequiredProps = createFunctionalComponent<RequiredPropsConfig>(
|
|
374
|
+
({ title, count, optional }) => (
|
|
375
|
+
<cx>
|
|
376
|
+
<div text={title} />
|
|
377
|
+
<div text={String(count)} />
|
|
378
|
+
{optional && <div text="optional shown" />}
|
|
379
|
+
</cx>
|
|
380
|
+
),
|
|
381
|
+
);
|
|
353
382
|
|
|
354
383
|
it("accepts all required props provided", () => {
|
|
355
384
|
const widget = (
|
package/src/util/Format.spec.ts
CHANGED
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
import assert from
|
|
2
|
-
import { Format } from
|
|
1
|
+
import assert from "assert";
|
|
2
|
+
import { Format } from "./Format";
|
|
3
3
|
|
|
4
|
-
describe(
|
|
5
|
-
describe(
|
|
6
|
-
it(
|
|
7
|
-
assert.equal(Format.value(0.5,
|
|
8
|
-
assert.equal(Format.value(0.50101,
|
|
9
|
-
assert.equal(Format.value(0.5012,
|
|
10
|
-
assert.equal(Format.value(0.0,
|
|
4
|
+
describe("Format", function () {
|
|
5
|
+
describe("n,number ", function () {
|
|
6
|
+
it("correctly formats numbers with min and max allowed precision", function () {
|
|
7
|
+
assert.equal(Format.value(0.5, "n;2;4"), "0.50");
|
|
8
|
+
assert.equal(Format.value(0.50101, "n;2;4"), "0.501");
|
|
9
|
+
assert.equal(Format.value(0.5012, "n;2;4"), "0.5012");
|
|
10
|
+
assert.equal(Format.value(0.0, "n;0;4"), "0");
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
it(
|
|
14
|
-
assert.equal(Format.value(0.5,
|
|
15
|
-
assert.equal(Format.value(0.50101,
|
|
16
|
-
assert.equal(Format.value(0.5016,
|
|
13
|
+
it("correctly formats numbers fixed precision", function () {
|
|
14
|
+
assert.equal(Format.value(0.5, "number;3"), "0.500");
|
|
15
|
+
assert.equal(Format.value(0.50101, "number;3"), "0.501");
|
|
16
|
+
assert.equal(Format.value(0.5016, "number;3"), "0.502");
|
|
17
17
|
});
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
describe(
|
|
21
|
-
it(
|
|
22
|
-
assert.equal(Format.value(0.5,
|
|
23
|
-
assert.equal(Format.value(0.50101,
|
|
24
|
-
assert.equal(Format.value(0.50123456,
|
|
25
|
-
assert.equal(Format.value(0.0,
|
|
20
|
+
describe("p,percentage", function () {
|
|
21
|
+
it("correctly formats numbers with min and max allowed precision", function () {
|
|
22
|
+
assert.equal(Format.value(0.5, "p;2;4"), "50.00%");
|
|
23
|
+
assert.equal(Format.value(0.50101, "p;2;4"), "50.101%");
|
|
24
|
+
assert.equal(Format.value(0.50123456, "p;2;4"), "50.1235%");
|
|
25
|
+
assert.equal(Format.value(0.0, "p;0;4"), "0%");
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
it(
|
|
29
|
-
assert.equal(Format.value(0.5,
|
|
30
|
-
assert.equal(Format.value(0.50101,
|
|
31
|
-
assert.equal(Format.value(0.5016,
|
|
28
|
+
it("correctly formats numbers fixed precision", function () {
|
|
29
|
+
assert.equal(Format.value(0.5, "percentage;3"), "50.000%");
|
|
30
|
+
assert.equal(Format.value(0.50101, "percentage;3"), "50.101%");
|
|
31
|
+
assert.equal(Format.value(0.5016, "percentage;3"), "50.160%");
|
|
32
32
|
});
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
describe(
|
|
36
|
-
it(
|
|
37
|
-
assert.equal(Format.value(new Date(2015, 3, 1),
|
|
35
|
+
describe("date,time,datetime", function () {
|
|
36
|
+
it("correctly formats dates", function () {
|
|
37
|
+
assert.equal(Format.value(new Date(2015, 3, 1), "d"), "4/1/2015");
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
it(
|
|
41
|
-
assert.equal(Format.value(new Date(2015, 3, 1, 16, 15, 14),
|
|
42
|
-
assert.equal(Format.value(new Date(2015, 3, 1, 5, 6, 14),
|
|
40
|
+
it("correctly formats time", function () {
|
|
41
|
+
assert.equal(Format.value(new Date(2015, 3, 1, 16, 15, 14), "t"), "16:15");
|
|
42
|
+
assert.equal(Format.value(new Date(2015, 3, 1, 5, 6, 14), "time"), "05:06");
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
it(
|
|
46
|
-
assert.equal(Format.value(new Date(2015, 3, 1, 5, 6, 14),
|
|
45
|
+
it("correctly formats date-time", function () {
|
|
46
|
+
assert.equal(Format.value(new Date(2015, 3, 1, 5, 6, 14), "dt"), "4/1/2015 05:06");
|
|
47
47
|
});
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
-
describe(
|
|
51
|
-
it(
|
|
52
|
-
assert.equal(Format.value(
|
|
50
|
+
describe("ellipsis", function () {
|
|
51
|
+
it("can shorten long texts", function () {
|
|
52
|
+
assert.equal(Format.value("This is a very long text.", "ellipsis;7"), "This...");
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
it(
|
|
56
|
-
assert.equal(Format.value(
|
|
55
|
+
it("can be used at the start of string", function () {
|
|
56
|
+
assert.equal(Format.value("This is a very long text.", "ellipsis;8;start"), "...text.");
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
it(
|
|
60
|
-
assert.equal(Format.value(
|
|
59
|
+
it("can be used in the middle of the string", function () {
|
|
60
|
+
assert.equal(Format.value("First (Middle) Last", "ellipsis;11;middle"), "Firs...Last");
|
|
61
61
|
});
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
-
describe(
|
|
65
|
-
it(
|
|
66
|
-
assert.equal(Format.value(null,
|
|
64
|
+
describe("null text", function () {
|
|
65
|
+
it("can contain null text", function () {
|
|
66
|
+
assert.equal(Format.value(null, "n;2|N/A"), "N/A");
|
|
67
67
|
});
|
|
68
68
|
});
|
|
69
69
|
});
|
|
@@ -1,72 +1,71 @@
|
|
|
1
|
-
import { Store } from "../../data/Store";
|
|
2
|
-
import { HotModule } from "../../ui/app/startHotAppLoop";
|
|
3
|
-
import { SubscriberList } from "../../util/SubscriberList";
|
|
4
|
-
import { Window } from "./Window";
|
|
5
|
-
import { View } from "../../data/View";
|
|
6
|
-
import { Instance } from "../../ui/Instance";
|
|
7
|
-
import { Overlay } from "./Overlay";
|
|
8
|
-
|
|
9
|
-
export interface HotPromiseWindowFactoryOptions {
|
|
10
|
-
parent?: Instance;
|
|
11
|
-
store?: View;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function createHotPromiseWindowFactoryWithProps<Props, R = any>(
|
|
15
|
-
module: HotModule,
|
|
16
|
-
factory: (props: Props) => (resolve: (value: R | PromiseLike<R>) => void, reject: (reason?: any) => void) => Overlay,
|
|
17
|
-
): (props: Props, options?: HotPromiseWindowFactoryOptions) => Promise<R> {
|
|
18
|
-
let subscriberList: SubscriberList | undefined;
|
|
19
|
-
if (module.hot) {
|
|
20
|
-
if (module.hot.data?.subscriberList) subscriberList = module.hot.data.subscriberList;
|
|
21
|
-
if (!subscriberList) subscriberList = new SubscriberList();
|
|
22
|
-
|
|
23
|
-
module.hot.dispose((data: any) => {
|
|
24
|
-
data.subscriberList = subscriberList;
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
module.hot.accept();
|
|
28
|
-
|
|
29
|
-
if (!subscriberList.isEmpty()) subscriberList.notify(factory);
|
|
30
|
-
|
|
31
|
-
subscriberList.subscribe((updatedFactory) => {
|
|
32
|
-
factory = updatedFactory;
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return (props: Props, options?: HotPromiseWindowFactoryOptions): Promise<R> => {
|
|
37
|
-
let store = options?.parent ?? options?.store ?? new Store();
|
|
38
|
-
let reloading = false;
|
|
39
|
-
return new Promise<R>((resolve, reject) => {
|
|
40
|
-
let dismiss: (() => void) | undefined;
|
|
41
|
-
let unsubscribe: (() => void) | undefined;
|
|
42
|
-
function rerun() {
|
|
43
|
-
dismiss?.();
|
|
44
|
-
let window = Window.create(factory(props)(resolve, reject) as any) as any;
|
|
45
|
-
window.overlayWillDismiss = () => {
|
|
46
|
-
if (!reloading && unsubscribe) unsubscribe();
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
1
|
+
import { Store } from "../../data/Store";
|
|
2
|
+
import { HotModule } from "../../ui/app/startHotAppLoop";
|
|
3
|
+
import { SubscriberList } from "../../util/SubscriberList";
|
|
4
|
+
import { Window } from "./Window";
|
|
5
|
+
import { View } from "../../data/View";
|
|
6
|
+
import { Instance } from "../../ui/Instance";
|
|
7
|
+
import { Overlay } from "./Overlay";
|
|
8
|
+
|
|
9
|
+
export interface HotPromiseWindowFactoryOptions {
|
|
10
|
+
parent?: Instance;
|
|
11
|
+
store?: View;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function createHotPromiseWindowFactoryWithProps<Props, R = any>(
|
|
15
|
+
module: HotModule,
|
|
16
|
+
factory: (props: Props) => (resolve: (value: R | PromiseLike<R>) => void, reject: (reason?: any) => void) => Overlay,
|
|
17
|
+
): (props: Props, options?: HotPromiseWindowFactoryOptions) => Promise<R> {
|
|
18
|
+
let subscriberList: SubscriberList | undefined;
|
|
19
|
+
if (module.hot) {
|
|
20
|
+
if (module.hot.data?.subscriberList) subscriberList = module.hot.data.subscriberList;
|
|
21
|
+
if (!subscriberList) subscriberList = new SubscriberList();
|
|
22
|
+
|
|
23
|
+
module.hot.dispose((data: any) => {
|
|
24
|
+
data.subscriberList = subscriberList;
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
module.hot.accept();
|
|
28
|
+
|
|
29
|
+
if (!subscriberList.isEmpty()) subscriberList.notify(factory);
|
|
30
|
+
|
|
31
|
+
subscriberList.subscribe((updatedFactory) => {
|
|
32
|
+
factory = updatedFactory;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return (props: Props, options?: HotPromiseWindowFactoryOptions): Promise<R> => {
|
|
37
|
+
let store = options?.parent ?? options?.store ?? new Store();
|
|
38
|
+
let reloading = false;
|
|
39
|
+
return new Promise<R>((resolve, reject) => {
|
|
40
|
+
let dismiss: (() => void) | undefined;
|
|
41
|
+
let unsubscribe: (() => void) | undefined;
|
|
42
|
+
function rerun() {
|
|
43
|
+
dismiss?.();
|
|
44
|
+
let window = Window.create(factory(props)(resolve, reject) as any) as any;
|
|
45
|
+
window.overlayWillDismiss = () => {
|
|
46
|
+
if (!reloading && unsubscribe) unsubscribe();
|
|
47
|
+
};
|
|
48
|
+
dismiss = window.open(store);
|
|
49
|
+
}
|
|
50
|
+
unsubscribe = subscriberList?.subscribe((updatedFactory: any) => {
|
|
51
|
+
factory = updatedFactory;
|
|
52
|
+
setTimeout(() => {
|
|
53
|
+
// timeout is required for proper module initialization
|
|
54
|
+
// sometimes elements are defined in the lower part of the module and if the function is run immediately, it will fail
|
|
55
|
+
reloading = true;
|
|
56
|
+
rerun();
|
|
57
|
+
reloading = false;
|
|
58
|
+
}, 10);
|
|
59
|
+
});
|
|
60
|
+
rerun();
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function createHotPromiseWindowFactory<R = any>(
|
|
66
|
+
module: HotModule,
|
|
67
|
+
factory: (resolve: (value: R | PromiseLike<R>) => void, reject: (reason?: any) => void) => Overlay,
|
|
68
|
+
): (options?: HotPromiseWindowFactoryOptions) => Promise<R> {
|
|
69
|
+
let result = createHotPromiseWindowFactoryWithProps(module, () => factory);
|
|
70
|
+
return (options?: HotPromiseWindowFactoryOptions) => result(null, options);
|
|
71
|
+
}
|