cx 24.7.1 → 24.7.3

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 (41) hide show
  1. package/dist/charts.js +10 -0
  2. package/dist/data.js +49 -19
  3. package/dist/manifest.js +731 -731
  4. package/dist/svg.js +6 -0
  5. package/dist/ui.js +3 -3
  6. package/package.json +1 -1
  7. package/src/charts/Legend.js +151 -151
  8. package/src/charts/LegendEntry.d.ts +17 -3
  9. package/src/charts/LegendEntry.js +4 -0
  10. package/src/charts/Marker.d.ts +14 -0
  11. package/src/charts/Marker.js +8 -0
  12. package/src/charts/PieLabel.js +71 -71
  13. package/src/charts/axis/Axis.d.ts +96 -96
  14. package/src/charts/axis/NumericAxis.js +347 -347
  15. package/src/charts/axis/Stack.js +55 -55
  16. package/src/data/ArrayElementView.js +37 -19
  17. package/src/data/ArrayElementView.spec.js +18 -0
  18. package/src/data/AugmentedViewBase.js +22 -14
  19. package/src/data/Binding.spec.js +69 -69
  20. package/src/data/StringTemplate.spec.js +105 -105
  21. package/src/data/getAccessor.spec.js +11 -11
  22. package/src/svg/Rectangle.d.ts +20 -7
  23. package/src/svg/Rectangle.js +7 -2
  24. package/src/svg/Text.d.ts +40 -40
  25. package/src/ui/Controller.d.ts +182 -182
  26. package/src/ui/Culture.js +129 -129
  27. package/src/ui/Cx.js +313 -313
  28. package/src/ui/DataProxy.spec.js +26 -23
  29. package/src/ui/FocusManager.js +171 -171
  30. package/src/ui/Instance.d.ts +72 -72
  31. package/src/ui/VDOM.d.ts +12 -12
  32. package/src/ui/app/startAppLoop.js +58 -58
  33. package/src/ui/index.d.ts +42 -42
  34. package/src/util/Console.d.ts +4 -4
  35. package/src/widgets/drag-drop/DropZone.js +214 -214
  36. package/src/widgets/form/TextField.js +289 -289
  37. package/src/widgets/form/UploadButton.d.ts +34 -34
  38. package/src/widgets/grid/variables.scss +88 -88
  39. package/src/widgets/overlay/Dropdown.js +612 -612
  40. package/src/widgets/overlay/Window.js +196 -196
  41. package/src/widgets/overlay/variables.scss +83 -83
package/dist/svg.js CHANGED
@@ -523,6 +523,8 @@ var Rectangle = /*#__PURE__*/ (function (_TextualBoundedObject) {
523
523
  colorIndex: undefined,
524
524
  fill: undefined,
525
525
  stroke: undefined,
526
+ rx: undefined,
527
+ ry: undefined,
526
528
  },
527
529
  ]),
528
530
  );
@@ -546,6 +548,8 @@ var Rectangle = /*#__PURE__*/ (function (_TextualBoundedObject) {
546
548
  style: data.style,
547
549
  fill: data.fill,
548
550
  stroke: data.stroke,
551
+ rx: data.rx,
552
+ ry: data.ry,
549
553
  }),
550
554
  this.renderChildren(context, instance),
551
555
  ],
@@ -557,6 +561,8 @@ var Rectangle = /*#__PURE__*/ (function (_TextualBoundedObject) {
557
561
  })(TextualBoundedObject);
558
562
  Rectangle.prototype.baseClass = "rectangle";
559
563
  Rectangle.prototype.anchors = "0 1 1 0";
564
+ Rectangle.prototype.rx = undefined;
565
+ Rectangle.prototype.ry = undefined;
560
566
  Widget.alias("rectangle", Rectangle);
561
567
 
562
568
  var ClipRect = /*#__PURE__*/ (function (_BoundedObject) {
package/dist/ui.js CHANGED
@@ -3958,15 +3958,15 @@ function startAppLoop(parentDOMElement, storeOrInstance, widget, options) {
3958
3958
  return function () {
3959
3959
  if (stopped) return;
3960
3960
  stopped = true;
3961
- if (!options.destroyDelay) destroy(parentDOMElement, options);
3961
+ if (!options.destroyDelay) destroy(parentDOMElement, options, root);
3962
3962
  else {
3963
3963
  setTimeout(function () {
3964
- destroy(parentDOMElement, options);
3964
+ destroy(parentDOMElement, options, root);
3965
3965
  }, options.destroyDelay);
3966
3966
  }
3967
3967
  };
3968
3968
  }
3969
- function destroy(parentDOMElement, options) {
3969
+ function destroy(parentDOMElement, options, root) {
3970
3970
  if (root) root.unmount();
3971
3971
  else VDOM.DOM.unmountComponentAtNode(parentDOMElement);
3972
3972
  if (options.removeParentDOMElement && parentDOMElement.parentNode)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cx",
3
- "version": "24.7.1",
3
+ "version": "24.7.3",
4
4
  "description": "Advanced JavaScript UI framework for admin and dashboard applications with ready to use grid, form and chart components.",
5
5
  "main": "index.js",
6
6
  "jsnext:main": "src/index.js",
@@ -1,151 +1,151 @@
1
- import { Widget, VDOM } from "../ui/Widget";
2
- import { HtmlElement } from "../widgets/HtmlElement";
3
- import { PureContainer } from "../ui/PureContainer";
4
- import { getShape } from "./shapes";
5
- import { isUndefined } from "../util/isUndefined";
6
- import { isArray } from "../util/isArray";
7
- import { withHoverSync } from "../ui/HoverSync";
8
-
9
- export class Legend extends HtmlElement {
10
- prepareData(context, instance) {
11
- let { data } = instance;
12
- data.stateMods = Object.assign(data.stateMods || {}, {
13
- vertical: this.vertical,
14
- });
15
- super.prepareData(context, instance);
16
- }
17
-
18
- declareData() {
19
- super.declareData(...arguments, {
20
- shape: undefined,
21
- });
22
- }
23
-
24
- isValidHtmlAttribute(attrName) {
25
- switch (attrName) {
26
- case "shapeSize":
27
- case "svgSize":
28
- case "shape":
29
- return false;
30
-
31
- default:
32
- return super.isValidHtmlAttribute(attrName);
33
- }
34
- }
35
-
36
- explore(context, instance) {
37
- if (!context.legends) context.legends = {};
38
-
39
- instance.legends = context.legends;
40
-
41
- context.addLegendEntry = (legendName, entry) => {
42
- if (!legendName) return;
43
-
44
- //case when all legends are scoped and new entry is added outside the scope
45
- if (!context.legends) return;
46
-
47
- let legend = context.legends[legendName];
48
- if (!legend)
49
- legend = context.legends[legendName] = {
50
- entries: [],
51
- names: {},
52
- };
53
-
54
- if (!legend.names[entry.name]) {
55
- legend.entries.push(entry);
56
- legend.names[entry.name] = entry;
57
- }
58
- };
59
-
60
- super.explore(context, instance);
61
- }
62
-
63
- renderChildren(context, instance) {
64
- const CSS = this.CSS;
65
-
66
- let entries = instance.legends[this.name] && instance.legends[this.name].entries,
67
- list;
68
-
69
- if (isArray(entries) && entries.length > 0) {
70
- list = (
71
- <div key="wrap" className={CSS.element(this.baseClass, "wrap")}>
72
- {entries.map((e, i) =>
73
- withHoverSync(i, e.hoverSync, e.hoverChannel, e.hoverId, ({ onMouseMove, onMouseLeave, hover }) => (
74
- <div
75
- key={i}
76
- className={CSS.element(this.baseClass, "entry", {
77
- "color-root": true,
78
- hover,
79
- disabled: e.disabled,
80
- selected: e.selected,
81
- })}
82
- onClick={e.onClick}
83
- onMouseMove={onMouseMove}
84
- onMouseLeave={onMouseLeave}
85
- >
86
- {this.renderShape(e, instance.data.shape)}
87
- {e.name}
88
- </div>
89
- )),
90
- )}
91
- </div>
92
- );
93
- }
94
-
95
- return [list, super.renderChildren(context, instance)];
96
- }
97
-
98
- renderShape(entry, legendEntriesShape) {
99
- const className = this.CSS.element(this.baseClass, "shape", {
100
- [`color-${entry.colorIndex}`]: entry.colorIndex != null && (isUndefined(entry.active) || entry.active),
101
- });
102
- const shape = getShape(legendEntriesShape || entry.shape || "square");
103
-
104
- return (
105
- <svg
106
- className={this.CSS.element(this.baseClass, "svg")}
107
- style={{
108
- width: `${this.svgSize}px`,
109
- height: `${this.svgSize}px`,
110
- marginTop: `${-this.svgSize / 2}px`,
111
- }}
112
- >
113
- {shape(this.svgSize / 2, this.svgSize / 2, entry.shapeSize || this.shapeSize, {
114
- style: entry.style,
115
- className: className,
116
- })}
117
- </svg>
118
- );
119
- }
120
- }
121
-
122
- Legend.prototype.name = "legend";
123
- Legend.prototype.baseClass = "legend";
124
- Legend.prototype.vertical = false;
125
- Legend.prototype.memoize = false;
126
- Legend.prototype.shapeSize = 18;
127
- Legend.prototype.shape = null;
128
- Legend.prototype.svgSize = 20;
129
-
130
- Widget.alias("legend", Legend);
131
-
132
- Legend.Scope = class extends PureContainer {
133
- explore(context, instance) {
134
- context.push("legends", (instance.legends = {}));
135
- super.explore(context, instance);
136
- }
137
-
138
- exploreCleanup(context, instance) {
139
- context.pop("legends");
140
- }
141
-
142
- prepare(context, instance) {
143
- context.push("legends", instance.legends);
144
- }
145
-
146
- prepareCleanup(context, instance) {
147
- context.pop("legends");
148
- }
149
- };
150
-
151
- export const LegendScope = Legend.Scope;
1
+ import { Widget, VDOM } from "../ui/Widget";
2
+ import { HtmlElement } from "../widgets/HtmlElement";
3
+ import { PureContainer } from "../ui/PureContainer";
4
+ import { getShape } from "./shapes";
5
+ import { isUndefined } from "../util/isUndefined";
6
+ import { isArray } from "../util/isArray";
7
+ import { withHoverSync } from "../ui/HoverSync";
8
+
9
+ export class Legend extends HtmlElement {
10
+ prepareData(context, instance) {
11
+ let { data } = instance;
12
+ data.stateMods = Object.assign(data.stateMods || {}, {
13
+ vertical: this.vertical,
14
+ });
15
+ super.prepareData(context, instance);
16
+ }
17
+
18
+ declareData() {
19
+ super.declareData(...arguments, {
20
+ shape: undefined,
21
+ });
22
+ }
23
+
24
+ isValidHtmlAttribute(attrName) {
25
+ switch (attrName) {
26
+ case "shapeSize":
27
+ case "svgSize":
28
+ case "shape":
29
+ return false;
30
+
31
+ default:
32
+ return super.isValidHtmlAttribute(attrName);
33
+ }
34
+ }
35
+
36
+ explore(context, instance) {
37
+ if (!context.legends) context.legends = {};
38
+
39
+ instance.legends = context.legends;
40
+
41
+ context.addLegendEntry = (legendName, entry) => {
42
+ if (!legendName) return;
43
+
44
+ //case when all legends are scoped and new entry is added outside the scope
45
+ if (!context.legends) return;
46
+
47
+ let legend = context.legends[legendName];
48
+ if (!legend)
49
+ legend = context.legends[legendName] = {
50
+ entries: [],
51
+ names: {},
52
+ };
53
+
54
+ if (!legend.names[entry.name]) {
55
+ legend.entries.push(entry);
56
+ legend.names[entry.name] = entry;
57
+ }
58
+ };
59
+
60
+ super.explore(context, instance);
61
+ }
62
+
63
+ renderChildren(context, instance) {
64
+ const CSS = this.CSS;
65
+
66
+ let entries = instance.legends[this.name] && instance.legends[this.name].entries,
67
+ list;
68
+
69
+ if (isArray(entries) && entries.length > 0) {
70
+ list = (
71
+ <div key="wrap" className={CSS.element(this.baseClass, "wrap")}>
72
+ {entries.map((e, i) =>
73
+ withHoverSync(i, e.hoverSync, e.hoverChannel, e.hoverId, ({ onMouseMove, onMouseLeave, hover }) => (
74
+ <div
75
+ key={i}
76
+ className={CSS.element(this.baseClass, "entry", {
77
+ "color-root": true,
78
+ hover,
79
+ disabled: e.disabled,
80
+ selected: e.selected,
81
+ })}
82
+ onClick={e.onClick}
83
+ onMouseMove={onMouseMove}
84
+ onMouseLeave={onMouseLeave}
85
+ >
86
+ {this.renderShape(e, instance.data.shape)}
87
+ {e.name}
88
+ </div>
89
+ )),
90
+ )}
91
+ </div>
92
+ );
93
+ }
94
+
95
+ return [list, super.renderChildren(context, instance)];
96
+ }
97
+
98
+ renderShape(entry, legendEntriesShape) {
99
+ const className = this.CSS.element(this.baseClass, "shape", {
100
+ [`color-${entry.colorIndex}`]: entry.colorIndex != null && (isUndefined(entry.active) || entry.active),
101
+ });
102
+ const shape = getShape(legendEntriesShape || entry.shape || "square");
103
+
104
+ return (
105
+ <svg
106
+ className={this.CSS.element(this.baseClass, "svg")}
107
+ style={{
108
+ width: `${this.svgSize}px`,
109
+ height: `${this.svgSize}px`,
110
+ marginTop: `${-this.svgSize / 2}px`,
111
+ }}
112
+ >
113
+ {shape(this.svgSize / 2, this.svgSize / 2, entry.shapeSize || this.shapeSize, {
114
+ style: entry.style,
115
+ className: className,
116
+ })}
117
+ </svg>
118
+ );
119
+ }
120
+ }
121
+
122
+ Legend.prototype.name = "legend";
123
+ Legend.prototype.baseClass = "legend";
124
+ Legend.prototype.vertical = false;
125
+ Legend.prototype.memoize = false;
126
+ Legend.prototype.shapeSize = 18;
127
+ Legend.prototype.shape = null;
128
+ Legend.prototype.svgSize = 20;
129
+
130
+ Widget.alias("legend", Legend);
131
+
132
+ Legend.Scope = class extends PureContainer {
133
+ explore(context, instance) {
134
+ context.push("legends", (instance.legends = {}));
135
+ super.explore(context, instance);
136
+ }
137
+
138
+ exploreCleanup(context, instance) {
139
+ context.pop("legends");
140
+ }
141
+
142
+ prepare(context, instance) {
143
+ context.push("legends", instance.legends);
144
+ }
145
+
146
+ prepareCleanup(context, instance) {
147
+ context.pop("legends");
148
+ }
149
+ };
150
+
151
+ export const LegendScope = Legend.Scope;
@@ -1,7 +1,7 @@
1
1
  import * as Cx from '../core';
2
2
 
3
3
  interface LegendEntryProps extends Cx.HtmlElementProps {
4
-
4
+
5
5
  /** Indicate that entry is selected. */
6
6
  selected?: Cx.BooleanProp,
7
7
 
@@ -28,11 +28,25 @@ interface LegendEntryProps extends Cx.HtmlElementProps {
28
28
 
29
29
  /** Base CSS class to be applied to the element. No class is applied by default. */
30
30
  baseClass?: string,
31
-
31
+
32
32
  legendAction?: string,
33
33
 
34
34
  /** Size of the svg shape container in pixels. Default value is 20. */
35
- svgSize?: number
35
+ svgSize?: number;
36
+
37
+ /**
38
+ * Applies to rectangular shapes. The horizontal corner radius of the rect. Defaults to ry if ry is specified.
39
+ * Value type: <length>|<percentage>;
40
+ * If unit is not specified, it defaults to `px`.
41
+ */
42
+ rx?: Cx.StringProp | Cx.NumberProp;
43
+
44
+ /**
45
+ * Applies to rectangular shapes. The vertical corner radius of the rect. Defaults to rx if rx is specified.
46
+ * Value type: <length>|<percentage>;
47
+ * If unit is not specified, it defaults to `px`.
48
+ */
49
+ ry?: Cx.StringProp | Cx.NumberProp;
36
50
  }
37
51
 
38
52
  export class LegendEntry extends Cx.Widget<LegendEntryProps> {}
@@ -23,6 +23,8 @@ export class LegendEntry extends HtmlElement {
23
23
  name: undefined,
24
24
  active: true,
25
25
  size: undefined,
26
+ rx: undefined,
27
+ ry: undefined
26
28
  });
27
29
  }
28
30
 
@@ -102,6 +104,8 @@ export class LegendEntry extends HtmlElement {
102
104
  {shape(this.svgSize / 2, this.svgSize / 2, entry.size, {
103
105
  style: entry.style,
104
106
  className: className,
107
+ rx: entry.rx,
108
+ ry: entry.ry
105
109
  })}
106
110
  </svg>
107
111
  );
@@ -91,6 +91,20 @@ interface MarkerProps extends BoundedObjectProps {
91
91
 
92
92
  /** Name of the stack. If multiple stacks are used, each should have a unique name. Default value is `stack`. */
93
93
  stack?: Cx.StringProp;
94
+
95
+ /**
96
+ * Applies to rectangular shapes. The horizontal corner radius of the rect. Defaults to ry if ry is specified.
97
+ * Value type: <length>|<percentage>;
98
+ * If unit is not specified, it defaults to `px`.
99
+ */
100
+ rx?: Cx.StringProp | Cx.NumberProp;
101
+
102
+ /**
103
+ * Applies to rectangular shapes. The vertical corner radius of the rect. Defaults to rx if rx is specified.
104
+ * Value type: <length>|<percentage>;
105
+ * If unit is not specified, it defaults to `px`.
106
+ */
107
+ ry?: Cx.StringProp | Cx.NumberProp;
94
108
  }
95
109
 
96
110
  export class Marker extends Cx.Widget<MarkerProps> {}
@@ -49,6 +49,8 @@ export class Marker extends BoundedObject {
49
49
  stack: undefined,
50
50
  stackedX: undefined,
51
51
  stackedY: undefined,
52
+ rx: undefined,
53
+ ry: undefined
52
54
  });
53
55
  }
54
56
 
@@ -272,6 +274,12 @@ class MarkerComponent extends VDOM.Component {
272
274
  widget.handleClick(e, instance);
273
275
  },
274
276
  };
277
+
278
+ if (shape == "rect" || shape == "square" || shape == "bar" || shape == "column") {
279
+ shapeProps.rx = data.rx;
280
+ shapeProps.ry = data.ry;
281
+ }
282
+
275
283
  if (widget.tooltip) {
276
284
  shapeProps.ref = (c) => {
277
285
  this.el = c;
@@ -1,71 +1,71 @@
1
- import { VDOM } from "../ui/Widget";
2
- import { BoundedObject } from "../svg/BoundedObject";
3
- import { Rect } from "../svg/util/Rect";
4
- import { parseStyle } from "../util/parseStyle";
5
-
6
- export class PieLabel extends BoundedObject {
7
- init() {
8
- this.lineStyle = parseStyle(this.lineStyle);
9
- super.init();
10
- }
11
-
12
- declareData(...args) {
13
- super.declareData(...args, {
14
- distance: undefined,
15
- lineStyle: { structured: true },
16
- lineStroke: undefined,
17
- lineClass: { structured: true },
18
- lineColorIndex: undefined,
19
- });
20
- }
21
-
22
- calculateBounds(context, instance) {
23
- var { data } = instance;
24
- var bounds = Rect.add(Rect.add(Rect.multiply(instance.parentRect, data.anchors), data.offset), data.margin);
25
- instance.originalBounds = bounds;
26
- instance.actualBounds = context.placePieLabel(bounds, data.distance);
27
- return new Rect({ t: 0, r: bounds.width(), b: bounds.height(), l: 0 });
28
- }
29
-
30
- prepare(context, instance) {
31
- super.prepare(context, instance);
32
- if (!context.registerPieLabel)
33
- throw new Error("PieLabel components are allowed only within PieLabelsContainer components.");
34
- let right = instance.parentRect.r > instance.parentRect.l;
35
- context.push("textDirection", right ? "right" : "left");
36
- context.registerPieLabel(instance);
37
- }
38
-
39
- prepareCleanup(context, instance) {
40
- context.pop("textDirection");
41
- }
42
-
43
- render(context, instance, key) {
44
- let { originalBounds, actualBounds, data } = instance;
45
-
46
- return (
47
- <g key={key} className={data.classNames}>
48
- <line
49
- className={this.CSS.element(
50
- this.baseClass,
51
- "line",
52
- data.lineColorIndex != null && "color-" + data.lineColorIndex
53
- )}
54
- x1={actualBounds.l < originalBounds.l ? actualBounds.r : actualBounds.l}
55
- y1={(actualBounds.t + actualBounds.b) / 2}
56
- x2={(originalBounds.l + originalBounds.r) / 2}
57
- y2={(originalBounds.t + originalBounds.b) / 2}
58
- stroke={data.lineStroke}
59
- style={data.lineStyle}
60
- />
61
- <g transform={`translate(${instance.actualBounds.l} ${instance.actualBounds.t})`}>
62
- {this.renderChildren(context, instance)}
63
- </g>
64
- </g>
65
- );
66
- }
67
- }
68
-
69
- PieLabel.prototype.distance = 100;
70
- PieLabel.prototype.baseClass = "pielabel";
71
- PieLabel.prototype.styled = true;
1
+ import { VDOM } from "../ui/Widget";
2
+ import { BoundedObject } from "../svg/BoundedObject";
3
+ import { Rect } from "../svg/util/Rect";
4
+ import { parseStyle } from "../util/parseStyle";
5
+
6
+ export class PieLabel extends BoundedObject {
7
+ init() {
8
+ this.lineStyle = parseStyle(this.lineStyle);
9
+ super.init();
10
+ }
11
+
12
+ declareData(...args) {
13
+ super.declareData(...args, {
14
+ distance: undefined,
15
+ lineStyle: { structured: true },
16
+ lineStroke: undefined,
17
+ lineClass: { structured: true },
18
+ lineColorIndex: undefined,
19
+ });
20
+ }
21
+
22
+ calculateBounds(context, instance) {
23
+ var { data } = instance;
24
+ var bounds = Rect.add(Rect.add(Rect.multiply(instance.parentRect, data.anchors), data.offset), data.margin);
25
+ instance.originalBounds = bounds;
26
+ instance.actualBounds = context.placePieLabel(bounds, data.distance);
27
+ return new Rect({ t: 0, r: bounds.width(), b: bounds.height(), l: 0 });
28
+ }
29
+
30
+ prepare(context, instance) {
31
+ super.prepare(context, instance);
32
+ if (!context.registerPieLabel)
33
+ throw new Error("PieLabel components are allowed only within PieLabelsContainer components.");
34
+ let right = instance.parentRect.r > instance.parentRect.l;
35
+ context.push("textDirection", right ? "right" : "left");
36
+ context.registerPieLabel(instance);
37
+ }
38
+
39
+ prepareCleanup(context, instance) {
40
+ context.pop("textDirection");
41
+ }
42
+
43
+ render(context, instance, key) {
44
+ let { originalBounds, actualBounds, data } = instance;
45
+
46
+ return (
47
+ <g key={key} className={data.classNames}>
48
+ <line
49
+ className={this.CSS.element(
50
+ this.baseClass,
51
+ "line",
52
+ data.lineColorIndex != null && "color-" + data.lineColorIndex
53
+ )}
54
+ x1={actualBounds.l < originalBounds.l ? actualBounds.r : actualBounds.l}
55
+ y1={(actualBounds.t + actualBounds.b) / 2}
56
+ x2={(originalBounds.l + originalBounds.r) / 2}
57
+ y2={(originalBounds.t + originalBounds.b) / 2}
58
+ stroke={data.lineStroke}
59
+ style={data.lineStyle}
60
+ />
61
+ <g transform={`translate(${instance.actualBounds.l} ${instance.actualBounds.t})`}>
62
+ {this.renderChildren(context, instance)}
63
+ </g>
64
+ </g>
65
+ );
66
+ }
67
+ }
68
+
69
+ PieLabel.prototype.distance = 100;
70
+ PieLabel.prototype.baseClass = "pielabel";
71
+ PieLabel.prototype.styled = true;