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
@@ -5,7 +5,7 @@ import { createTestRenderer } from "../util/test/createTestRenderer";
5
5
  import { invokeCallback } from "./invokeCallback";
6
6
 
7
7
  describe("invokeCallback", () => {
8
- it("works with functions", () => {
8
+ it("works with functions", async () => {
9
9
  const FComp = createFunctionalComponent(({ onTest }: { onTest: (v: any) => void }) => {
10
10
  invokeCallback(null!, onTest, "works");
11
11
  return (
@@ -17,7 +17,7 @@ describe("invokeCallback", () => {
17
17
 
18
18
  let store = new Store();
19
19
  let value;
20
- const component = createTestRenderer(store, {
20
+ const component = await createTestRenderer(store, {
21
21
  type: FComp,
22
22
  onTest: (v: any) => {
23
23
  value = v;
@@ -28,7 +28,7 @@ describe("invokeCallback", () => {
28
28
  assert.equal(value, "works");
29
29
  });
30
30
 
31
- it("works with controller methods", () => {
31
+ it("works with controller methods", async () => {
32
32
  const FComp = createFunctionalComponent(({ onTest }: { onTest: (v: any) => void }) => {
33
33
  return (
34
34
  <cx>
@@ -43,7 +43,7 @@ describe("invokeCallback", () => {
43
43
 
44
44
  let store = new Store();
45
45
  let value;
46
- const component = createTestRenderer(store, {
46
+ const component = await createTestRenderer(store, {
47
47
  type: FComp,
48
48
  onTest: "onTest",
49
49
  controller: {
@@ -5,7 +5,7 @@ import { createTestRenderer } from "../util/test/createTestRenderer";
5
5
  import { resolveCallback } from "./resolveCallback";
6
6
 
7
7
  describe("resolveCallback", () => {
8
- it("works with functions", () => {
8
+ it("works with functions", async () => {
9
9
  const FComp = createFunctionalComponent(({ onTest }: { onTest: (value: string) => void }) => {
10
10
  let callback = resolveCallback(onTest);
11
11
  assert(typeof callback === "function");
@@ -19,7 +19,7 @@ describe("resolveCallback", () => {
19
19
 
20
20
  let store = new Store();
21
21
  let value;
22
- const component = createTestRenderer(
22
+ const component = await createTestRenderer(
23
23
  store,
24
24
  <cx>
25
25
  <FComp
@@ -34,7 +34,7 @@ describe("resolveCallback", () => {
34
34
  assert.equal(value, "works");
35
35
  });
36
36
 
37
- it("works with controller methods", () => {
37
+ it("works with controller methods", async () => {
38
38
  const FComp = createFunctionalComponent(({ onTest }: { onTest: string | ((value: string) => void) }) => {
39
39
  let callback = resolveCallback(onTest);
40
40
  assert(typeof callback === "function");
@@ -51,7 +51,7 @@ describe("resolveCallback", () => {
51
51
 
52
52
  let store = new Store();
53
53
  let value;
54
- const component = createTestRenderer(
54
+ const component = await createTestRenderer(
55
55
  store,
56
56
  <cx>
57
57
  <FComp
@@ -7,7 +7,7 @@ import { createFunctionalComponent } from "../ui/createFunctionalComponent";
7
7
  import { ref } from "./store";
8
8
 
9
9
  describe("ref", () => {
10
- it("allows store references in functional components", () => {
10
+ it("allows store references in functional components", async () => {
11
11
  const FComp = createFunctionalComponent(({}) => {
12
12
  let testValue = ref({ bind: "x", defaultValue: 10 });
13
13
  return (
@@ -19,7 +19,7 @@ describe("ref", () => {
19
19
 
20
20
  let store = new Store();
21
21
 
22
- const component = createTestRenderer(store, FComp);
22
+ const component = await createTestRenderer(store, FComp);
23
23
 
24
24
  let tree = component.toJSON();
25
25
  assert.deepEqual(tree, {
@@ -29,7 +29,7 @@ describe("ref", () => {
29
29
  });
30
30
  });
31
31
 
32
- it("can be used to adapt any prop passed to a functional component", () => {
32
+ it("can be used to adapt any prop passed to a functional component", async () => {
33
33
  const FComp = createFunctionalComponent(({ value }: { value: Prop<any> }) => {
34
34
  return (
35
35
  <cx>
@@ -40,8 +40,8 @@ describe("ref", () => {
40
40
 
41
41
  let store = new Store({ data: { value: 100 } });
42
42
 
43
- function test(value: Prop<any>, expectation: any) {
44
- const component = createTestRenderer(store, <FComp value={value} />);
43
+ async function test(value: Prop<any>, expectation: any) {
44
+ const component = await createTestRenderer(store, <FComp value={value} />);
45
45
  let tree = component.toJSON();
46
46
  assert.deepEqual(tree, {
47
47
  type: "div",
@@ -50,18 +50,18 @@ describe("ref", () => {
50
50
  });
51
51
  }
52
52
 
53
- test({ bind: "value" }, "x100");
54
- test({ expr: "{value}" }, "x100");
55
- test({ tpl: "{value:n;2}" }, "x100.00");
56
- test(200, "x200");
57
- test(() => 500, "x500");
58
- test(
53
+ await test({ bind: "value" }, "x100");
54
+ await test({ expr: "{value}" }, "x100");
55
+ await test({ tpl: "{value:n;2}" }, "x100.00");
56
+ await test(200, "x200");
57
+ await test(() => 500, "x500");
58
+ await test(
59
59
  computable("value", (value: string) => value + 100),
60
60
  "x200",
61
61
  );
62
- test(null, "xnull");
63
- test(undefined, "xundefined");
64
- test(0, "x0");
65
- test(false, "xfalse");
62
+ await test(null, "xnull");
63
+ await test(undefined, "xundefined");
64
+ await test(0, "x0");
65
+ await test(false, "xfalse");
66
66
  });
67
67
  });
@@ -1,11 +1,11 @@
1
1
  import assert from "assert";
2
- import { createTestRenderer } from "../util/test/createTestRenderer";
2
+ import { createTestRenderer, act } from "../util/test/createTestRenderer";
3
3
  import { Store } from "../data/Store";
4
4
  import { createFunctionalComponent } from "../ui/createFunctionalComponent";
5
5
  import { useTrigger } from "./useTrigger";
6
6
 
7
7
  describe("useTrigger", () => {
8
- it("works", () => {
8
+ it("works", async () => {
9
9
  let last = null;
10
10
 
11
11
  const FComp = createFunctionalComponent(({ ...props }) => {
@@ -23,17 +23,19 @@ describe("useTrigger", () => {
23
23
  let store = new Store();
24
24
  let test = store.ref("test", 1);
25
25
 
26
- const component = createTestRenderer(store, FComp);
26
+ const component = await createTestRenderer(store, FComp);
27
27
 
28
28
  component.toJSON();
29
29
  assert.equal(last, null); //trigger did not fire because it didn't receive true as the last argument
30
30
 
31
- test.set(2);
31
+ await act(async () => {
32
+ test.set(2);
33
+ });
32
34
  component.toJSON();
33
35
  assert.equal(last, 2);
34
36
  });
35
37
 
36
- it("fires immediately if the last argument is true", () => {
38
+ it("fires immediately if the last argument is true", async () => {
37
39
  let last = null;
38
40
 
39
41
  const FComp = createFunctionalComponent(({ ...props }) => {
@@ -55,17 +57,19 @@ describe("useTrigger", () => {
55
57
  let store = new Store();
56
58
  let test = store.ref("test", 1);
57
59
 
58
- const component = createTestRenderer(store, FComp);
60
+ const component = await createTestRenderer(store, FComp);
59
61
 
60
62
  component.toJSON();
61
63
  assert.equal(last, 1);
62
64
 
63
- test.set(2);
65
+ await act(async () => {
66
+ test.set(2);
67
+ });
64
68
  component.toJSON();
65
69
  assert.equal(last, 2);
66
70
  });
67
71
 
68
- it("accepts refs as arguments", () => {
72
+ it("accepts refs as arguments", async () => {
69
73
  let last = null;
70
74
 
71
75
  let store = new Store();
@@ -87,12 +91,14 @@ describe("useTrigger", () => {
87
91
  );
88
92
  });
89
93
 
90
- const component = createTestRenderer(store, FComp);
94
+ const component = await createTestRenderer(store, FComp);
91
95
 
92
96
  component.toJSON();
93
97
  assert.equal(last, 1);
94
98
 
95
- test.set(2);
99
+ await act(async () => {
100
+ test.set(2);
101
+ });
96
102
  component.toJSON();
97
103
  assert.equal(last, 2);
98
104
  });
@@ -1,4 +1,4 @@
1
- import { jsx, jsxs } from "./jsx-runtime";
2
-
3
- export const jsxDEV = jsx;
4
- export const jsxsDEV = jsxs;
1
+ import { jsx, jsxs } from "./jsx-runtime";
2
+
3
+ export const jsxDEV = jsx;
4
+ export const jsxsDEV = jsxs;
@@ -1,79 +1,79 @@
1
- import type { ComponentClass, FunctionComponent, JSX as ReactJSX } from "react";
2
- import type { CxFunctionalComponent } from "./ui/createFunctionalComponent";
3
- import { Widget } from "./ui/Widget";
4
- import { isArray } from "./util/isArray";
5
- import { isString } from "./util/isString";
6
- import { HtmlElement, HtmlElementConfig } from "./widgets/HtmlElement";
7
- import { ReactElementWrapper, ReactElementWrapperConfig } from "./widgets/ReactElementWrapper";
8
-
9
- export function jsx(typeName: any, props: any, key?: string): any {
10
- if (isArray(typeName)) return typeName;
11
-
12
- // if (isFunction(typeName) && isUndefined(props))
13
- // return createFunctionalComponent((config) => typeName(flattenProps(config)));
14
-
15
- if (typeName.type || typeName.$type) return typeName;
16
-
17
- if (props.children && isArray(props.children) && props.children.length == 0) props.children = null;
18
-
19
- if (props.children && props.children.length == 1) props.children = props.children[0];
20
-
21
- if (typeName == "cx") return props.children;
22
-
23
- if (isString(typeName) && typeName[0] == typeName[0].toLowerCase()) {
24
- props.tag = typeName;
25
- typeName = HtmlElement;
26
- }
27
- // React components (functions/classes without isComponentType and not CxJS functional components) should go through ReactElementWrapper
28
- else if (typeof typeName === "function" && !typeName.isComponentType && !typeName.$isComponentFactory) {
29
- props.componentType = typeName;
30
- typeName = ReactElementWrapper;
31
- }
32
-
33
- return {
34
- $type: typeName,
35
- ...props,
36
- jsxAttributes: props && Object.keys(props),
37
- };
38
- }
39
-
40
- export const jsxs = jsx;
41
-
42
- type ReactIntrinsicElements = ReactJSX.IntrinsicElements;
43
-
44
- type CxIntrinsicElements = {
45
- [K in keyof ReactIntrinsicElements]: HtmlElementConfig<K>;
46
- };
47
-
48
- // Helper type to transform props for React components (but not CxJS functional components)
49
- // Uses a workaround to avoid TypeScript inference issues with conditional types in LibraryManagedAttributes
50
- // We use Omit to exclude componentType since it's added automatically by the jsx-runtime
51
- type TransformReactComponentProps<C, P> = [C] extends [CxFunctionalComponent<any>]
52
- ? P // CxJS functional components already have proper types
53
- : [C] extends [FunctionComponent<any>]
54
- ? ReactElementWrapperConfig<P>
55
- : [C] extends [ComponentClass<any>]
56
- ? ReactElementWrapperConfig<P>
57
- : P;
58
-
59
- export namespace JSX {
60
- /**
61
- * Base class for JSX element instances.
62
- * All widgets must extend from Widget class or React.Component.
63
- */
64
- export type ElementClass = Widget<any> | React.Component<any, any>;
65
-
66
- /**
67
- * Intrinsic JSX elements (HTML-like tags).
68
- * Supports HTML elements that map to HtmlElement widgets.
69
- */
70
- export interface IntrinsicElements extends CxIntrinsicElements {
71
- cx: any;
72
- }
73
-
74
- /**
75
- * Transform props for React function components used in CxJS JSX.
76
- * Adds standard WidgetConfig properties and transforms React props to Prop<X>.
77
- */
78
- export type LibraryManagedAttributes<C, P> = TransformReactComponentProps<C, P>;
79
- }
1
+ import type { ComponentClass, FunctionComponent, JSX as ReactJSX } from "react";
2
+ import type { CxFunctionalComponent } from "./ui/createFunctionalComponent";
3
+ import { Widget } from "./ui/Widget";
4
+ import { isArray } from "./util/isArray";
5
+ import { isString } from "./util/isString";
6
+ import { HtmlElement, HtmlElementConfig } from "./widgets/HtmlElement";
7
+ import { ReactElementWrapper, ReactElementWrapperConfig } from "./widgets/ReactElementWrapper";
8
+
9
+ export function jsx(typeName: any, props: any, key?: string): any {
10
+ if (isArray(typeName)) return typeName;
11
+
12
+ // if (isFunction(typeName) && isUndefined(props))
13
+ // return createFunctionalComponent((config) => typeName(flattenProps(config)));
14
+
15
+ if (typeName.type || typeName.$type) return typeName;
16
+
17
+ if (props.children && isArray(props.children) && props.children.length == 0) props.children = null;
18
+
19
+ if (props.children && props.children.length == 1) props.children = props.children[0];
20
+
21
+ if (typeName == "cx") return props.children;
22
+
23
+ if (isString(typeName) && typeName[0] == typeName[0].toLowerCase()) {
24
+ props.tag = typeName;
25
+ typeName = HtmlElement;
26
+ }
27
+ // React components (functions/classes without isComponentType and not CxJS functional components) should go through ReactElementWrapper
28
+ else if (typeof typeName === "function" && !typeName.isComponentType && !typeName.$isComponentFactory) {
29
+ props.componentType = typeName;
30
+ typeName = ReactElementWrapper;
31
+ }
32
+
33
+ return {
34
+ $type: typeName,
35
+ ...props,
36
+ jsxAttributes: props && Object.keys(props),
37
+ };
38
+ }
39
+
40
+ export const jsxs = jsx;
41
+
42
+ type ReactIntrinsicElements = ReactJSX.IntrinsicElements;
43
+
44
+ type CxIntrinsicElements = {
45
+ [K in keyof ReactIntrinsicElements]: HtmlElementConfig<K>;
46
+ };
47
+
48
+ // Helper type to transform props for React components (but not CxJS functional components)
49
+ // Uses a workaround to avoid TypeScript inference issues with conditional types in LibraryManagedAttributes
50
+ // We use Omit to exclude componentType since it's added automatically by the jsx-runtime
51
+ type TransformReactComponentProps<C, P> = [C] extends [CxFunctionalComponent<any>]
52
+ ? P // CxJS functional components already have proper types
53
+ : [C] extends [FunctionComponent<any>]
54
+ ? ReactElementWrapperConfig<P>
55
+ : [C] extends [ComponentClass<any>]
56
+ ? ReactElementWrapperConfig<P>
57
+ : P;
58
+
59
+ export namespace JSX {
60
+ /**
61
+ * Base class for JSX element instances.
62
+ * All widgets must extend from Widget class or React.Component.
63
+ */
64
+ export type ElementClass = Widget<any> | React.Component<any, any>;
65
+
66
+ /**
67
+ * Intrinsic JSX elements (HTML-like tags).
68
+ * Supports HTML elements that map to HtmlElement widgets.
69
+ */
70
+ export interface IntrinsicElements extends CxIntrinsicElements {
71
+ cx: any;
72
+ }
73
+
74
+ /**
75
+ * Transform props for React function components used in CxJS JSX.
76
+ * Adds standard WidgetConfig properties and transforms React props to Prop<X>.
77
+ */
78
+ export type LibraryManagedAttributes<C, P> = TransformReactComponentProps<C, P>;
79
+ }
package/src/ui/CSS.ts CHANGED
@@ -1,87 +1,87 @@
1
- import { CSSHelper } from "./CSSHelper";
2
- import { parseStyle } from "../util/parseStyle";
3
- import { isArray } from "../util/isArray";
4
-
5
- function push(list: any[] | undefined, item: any): any[] {
6
- if (!item) return list || [];
7
- if (!list) list = [];
8
- list.push(item);
9
- return list;
10
- }
11
-
12
- function pushMore(list: any[] | undefined, itemArray: any[]): any[] {
13
- if (!itemArray || itemArray.length == 0) return list || [];
14
- if (!list) list = [];
15
- list.push.apply(list, itemArray);
16
- return list;
17
- }
18
-
19
- function pushMap(list: any[] | undefined, itemArray: any[] | undefined, mapF: (item: any) => any): any[] | undefined {
20
- return itemArray ? pushMore(list, itemArray.map(mapF)) : list;
21
- }
22
-
23
- function join(list: any[] | undefined): string | undefined {
24
- return list ? list.join(" ") : undefined;
25
- }
26
-
27
- export class CSS {
28
- public static classPrefix: string;
29
-
30
- static resolve(...args: any[]): any[] {
31
- let list: any[] | undefined = undefined,
32
- type: string,
33
- arg: any,
34
- i: number,
35
- key: string;
36
-
37
- for (i = 0; i < args.length; i++) {
38
- arg = args[i];
39
- if (arg) {
40
- type = typeof arg;
41
- if (type == "string") list = push(list, arg);
42
- else if (type == "object") {
43
- if (isArray(arg)) list = pushMore(list, this.resolve(...arg));
44
- else for (key in arg) if (arg[key]) list = push(list, key);
45
- }
46
- }
47
- }
48
- return list || [];
49
- }
50
-
51
- static block(baseClass: string, styleModifiers?: any, stateModifiers?: any): string;
52
- static block(baseClass?: string, styleModifiers?: any, stateModifiers?: any): string | undefined {
53
- let list: any[] | undefined;
54
- if (baseClass) list = push(list, this.classPrefix + "b-" + baseClass);
55
- list = pushMap(list, this.resolve(styleModifiers), (m) => this.classPrefix + "m-" + m);
56
- list = pushMap(list, this.resolve(stateModifiers), (m) => this.classPrefix + "s-" + m);
57
- return join(list);
58
- }
59
-
60
- static element(baseClass: string, elementClass: string, stateModifiers?: any): string;
61
- static element(baseClass?: string, elementClass?: string, stateModifiers?: any): string | undefined {
62
- let list: any[] | undefined;
63
- if (baseClass && elementClass) list = push(list, this.classPrefix + "e-" + baseClass + "-" + elementClass);
64
- list = pushMap(list, this.resolve(stateModifiers), (m) => this.classPrefix + "s-" + m);
65
- return join(list);
66
- }
67
-
68
- static state(stateModifiers: any): string | undefined {
69
- return join(pushMap(undefined, this.resolve(stateModifiers), (m) => this.classPrefix + "s-" + m));
70
- }
71
-
72
- static mod(mods: any): string | undefined {
73
- return join(pushMap(undefined, this.resolve(mods), (m) => this.classPrefix + "m-" + m));
74
- }
75
-
76
- static expand(...args: any[]): string | undefined {
77
- return join(this.resolve(...args));
78
- }
79
-
80
- static parseStyle(str: any): any {
81
- return parseStyle(str);
82
- }
83
- }
84
-
85
- CSS.classPrefix = "cx";
86
-
87
- CSSHelper.alias("cx", CSS);
1
+ import { CSSHelper } from "./CSSHelper";
2
+ import { parseStyle } from "../util/parseStyle";
3
+ import { isArray } from "../util/isArray";
4
+
5
+ function push(list: any[] | undefined, item: any): any[] {
6
+ if (!item) return list || [];
7
+ if (!list) list = [];
8
+ list.push(item);
9
+ return list;
10
+ }
11
+
12
+ function pushMore(list: any[] | undefined, itemArray: any[]): any[] {
13
+ if (!itemArray || itemArray.length == 0) return list || [];
14
+ if (!list) list = [];
15
+ list.push.apply(list, itemArray);
16
+ return list;
17
+ }
18
+
19
+ function pushMap(list: any[] | undefined, itemArray: any[] | undefined, mapF: (item: any) => any): any[] | undefined {
20
+ return itemArray ? pushMore(list, itemArray.map(mapF)) : list;
21
+ }
22
+
23
+ function join(list: any[] | undefined): string | undefined {
24
+ return list ? list.join(" ") : undefined;
25
+ }
26
+
27
+ export class CSS {
28
+ public static classPrefix: string;
29
+
30
+ static resolve(...args: any[]): any[] {
31
+ let list: any[] | undefined = undefined,
32
+ type: string,
33
+ arg: any,
34
+ i: number,
35
+ key: string;
36
+
37
+ for (i = 0; i < args.length; i++) {
38
+ arg = args[i];
39
+ if (arg) {
40
+ type = typeof arg;
41
+ if (type == "string") list = push(list, arg);
42
+ else if (type == "object") {
43
+ if (isArray(arg)) list = pushMore(list, this.resolve(...arg));
44
+ else for (key in arg) if (arg[key]) list = push(list, key);
45
+ }
46
+ }
47
+ }
48
+ return list || [];
49
+ }
50
+
51
+ static block(baseClass: string, styleModifiers?: any, stateModifiers?: any): string;
52
+ static block(baseClass?: string, styleModifiers?: any, stateModifiers?: any): string | undefined {
53
+ let list: any[] | undefined;
54
+ if (baseClass) list = push(list, this.classPrefix + "b-" + baseClass);
55
+ list = pushMap(list, this.resolve(styleModifiers), (m) => this.classPrefix + "m-" + m);
56
+ list = pushMap(list, this.resolve(stateModifiers), (m) => this.classPrefix + "s-" + m);
57
+ return join(list);
58
+ }
59
+
60
+ static element(baseClass: string, elementClass: string, stateModifiers?: any): string;
61
+ static element(baseClass?: string, elementClass?: string, stateModifiers?: any): string | undefined {
62
+ let list: any[] | undefined;
63
+ if (baseClass && elementClass) list = push(list, this.classPrefix + "e-" + baseClass + "-" + elementClass);
64
+ list = pushMap(list, this.resolve(stateModifiers), (m) => this.classPrefix + "s-" + m);
65
+ return join(list);
66
+ }
67
+
68
+ static state(stateModifiers: any): string | undefined {
69
+ return join(pushMap(undefined, this.resolve(stateModifiers), (m) => this.classPrefix + "s-" + m));
70
+ }
71
+
72
+ static mod(mods: any): string | undefined {
73
+ return join(pushMap(undefined, this.resolve(mods), (m) => this.classPrefix + "m-" + m));
74
+ }
75
+
76
+ static expand(...args: any[]): string | undefined {
77
+ return join(this.resolve(...args));
78
+ }
79
+
80
+ static parseStyle(str: any): any {
81
+ return parseStyle(str);
82
+ }
83
+ }
84
+
85
+ CSS.classPrefix = "cx";
86
+
87
+ CSSHelper.alias("cx", CSS);