cx 24.3.1 → 24.3.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.
@@ -1,88 +1,88 @@
1
- import { Widget, VDOM } from "../../ui/Widget";
2
- import { HtmlElement } from "../HtmlElement";
3
- import { FocusManager } from "../../ui/FocusManager";
4
- import { isArray } from "../../util/isArray";
5
- import { coalesce } from "../../util/coalesce";
6
-
7
- export class Label extends HtmlElement {
8
- declareData() {
9
- super.declareData(...arguments, {
10
- required: undefined,
11
- disabled: undefined,
12
- htmlFor: undefined,
13
- });
14
- }
15
-
16
- prepareData(context, instance) {
17
- let { data } = instance;
18
- data.stateMods = {
19
- ...data.stateMods,
20
- disabled: data.disabled,
21
- };
22
- data._disabled = data.disabled;
23
- super.prepareData(context, instance);
24
- }
25
-
26
- explore(context, instance) {
27
- let { data } = instance;
28
-
29
- if (!data.htmlFor) data.htmlFor = context.lastFieldId;
30
-
31
- data.disabled = data.stateMods.disabled = coalesce(
32
- context.parentStrict ? context.parentDisabled : null,
33
- data._disabled,
34
- context.parentDisabled
35
- );
36
-
37
- data.asterisk = context.parentAsterisk || this.asterisk;
38
-
39
- if (instance.cache("disabled", data.disabled) || instance.cache("asterisk", data.asterisk)) {
40
- instance.markShouldUpdate(context);
41
- this.prepareCSS(context, instance);
42
- }
43
-
44
- super.explore(context, instance);
45
- }
46
-
47
- isValidHtmlAttribute(attrName) {
48
- switch (attrName) {
49
- case "asterisk":
50
- case "required":
51
- return false;
52
- }
53
- return super.isValidHtmlAttribute(attrName);
54
- }
55
-
56
- attachProps(context, instance, props) {
57
- super.attachProps(context, instance, props);
58
-
59
- let { data } = instance;
60
-
61
- if (data.htmlFor) {
62
- props.htmlFor = data.htmlFor;
63
-
64
- if (!props.onClick)
65
- props.onClick = () => {
66
- //additional focus for LookupFields which are not input based
67
- let el = document.getElementById(instance.data.htmlFor);
68
- if (el) FocusManager.focusFirst(el);
69
- };
70
- }
71
-
72
- if (!props.id && data.htmlFor) props.id = `${data.htmlFor}-label`;
73
-
74
- if (data.required && data.asterisk) {
75
- if (!isArray(props.children)) props.children = [props.children];
76
- props.children.push(" ");
77
- props.children.push(
78
- <span key="asterisk" className={this.CSS.element(this.baseClass, "asterisk")}>
79
- *
80
- </span>
81
- );
82
- }
83
- }
84
- }
85
-
86
- Label.prototype.baseClass = "label";
87
- Label.prototype.tag = "label";
88
- Label.prototype.asterisk = false;
1
+ import { Widget, VDOM } from "../../ui/Widget";
2
+ import { HtmlElement } from "../HtmlElement";
3
+ import { FocusManager } from "../../ui/FocusManager";
4
+ import { isArray } from "../../util/isArray";
5
+ import { coalesce } from "../../util/coalesce";
6
+
7
+ export class Label extends HtmlElement {
8
+ declareData() {
9
+ super.declareData(...arguments, {
10
+ required: undefined,
11
+ disabled: undefined,
12
+ htmlFor: undefined,
13
+ });
14
+ }
15
+
16
+ prepareData(context, instance) {
17
+ let { data } = instance;
18
+ data.stateMods = {
19
+ ...data.stateMods,
20
+ disabled: data.disabled,
21
+ };
22
+ data._disabled = data.disabled;
23
+ super.prepareData(context, instance);
24
+ }
25
+
26
+ explore(context, instance) {
27
+ let { data } = instance;
28
+
29
+ if (!data.htmlFor) data.htmlFor = context.lastFieldId;
30
+
31
+ data.disabled = data.stateMods.disabled = coalesce(
32
+ context.parentStrict ? context.parentDisabled : null,
33
+ data._disabled,
34
+ context.parentDisabled
35
+ );
36
+
37
+ data.asterisk = context.parentAsterisk || this.asterisk;
38
+
39
+ if (instance.cache("disabled", data.disabled) || instance.cache("asterisk", data.asterisk)) {
40
+ instance.markShouldUpdate(context);
41
+ this.prepareCSS(context, instance);
42
+ }
43
+
44
+ super.explore(context, instance);
45
+ }
46
+
47
+ isValidHtmlAttribute(attrName) {
48
+ switch (attrName) {
49
+ case "asterisk":
50
+ case "required":
51
+ return false;
52
+ }
53
+ return super.isValidHtmlAttribute(attrName);
54
+ }
55
+
56
+ attachProps(context, instance, props) {
57
+ super.attachProps(context, instance, props);
58
+
59
+ let { data } = instance;
60
+
61
+ if (data.htmlFor) {
62
+ props.htmlFor = data.htmlFor;
63
+
64
+ if (!props.onClick)
65
+ props.onClick = () => {
66
+ //additional focus for LookupFields which are not input based
67
+ let el = document.getElementById(instance.data.htmlFor);
68
+ if (el) FocusManager.focusFirst(el);
69
+ };
70
+ }
71
+
72
+ if (!props.id && data.htmlFor) props.id = `${data.htmlFor}-label`;
73
+
74
+ if (data.required && data.asterisk) {
75
+ if (!isArray(props.children)) props.children = [props.children];
76
+ props.children.push(" ");
77
+ props.children.push(
78
+ <span key="asterisk" className={this.CSS.element(this.baseClass, "asterisk")}>
79
+ *
80
+ </span>
81
+ );
82
+ }
83
+ }
84
+ }
85
+
86
+ Label.prototype.baseClass = "label";
87
+ Label.prototype.tag = "label";
88
+ Label.prototype.asterisk = false;
@@ -1,34 +1,34 @@
1
- import * as Cx from "../../core";
2
- import { FieldProps } from "./Field";
3
-
4
- interface UploadButtonProps extends FieldProps {
5
- /** Text description. */
6
- text?: Cx.StringProp;
7
-
8
- url?: Cx.StringProp;
9
-
10
- /** Base CSS class to be applied to the element. Default is 'uploadbutton'. */
11
- baseClass?: string;
12
-
13
- /** Defaults to `false`. Set to `true` to enable multiple selection. */
14
- multiple?: boolean;
15
-
16
- method?: string;
17
- uploadInProgressText?: string;
18
-
19
- /** Defaults to `false`. Set to `true` to abort uploads if the button is destroyed (unmounted). */
20
- abortOnDestroy?: boolean;
21
-
22
- /** Defines file types that are accepted for upload. */
23
- accept?: Cx.StringProp;
24
-
25
- /** Name of the icon to be put on the left side of the button. */
26
- icon?: Cx.StringProp;
27
-
28
- onUploadStarting?: ((xhr: XMLHttpRequest, instance: any, file: File, formData: FormData) => boolean) | string;
29
- onUploadComplete?: ((xhr: XMLHttpRequest, instance: any, file: File, formData: FormData) => void) | string;
30
- onUploadProgress?: ((event: ProgressEvent, instance: any, file: File, formData: FormData) => void) | string;
31
- onUploadError?: ((event: ProgressEvent, instance: any, file: File, formData: FormData) => void) | string;
32
- }
33
-
34
- export class UploadButton extends Cx.Widget<UploadButtonProps> {}
1
+ import * as Cx from "../../core";
2
+ import { FieldProps } from "./Field";
3
+
4
+ interface UploadButtonProps extends FieldProps {
5
+ /** Text description. */
6
+ text?: Cx.StringProp;
7
+
8
+ url?: Cx.StringProp;
9
+
10
+ /** Base CSS class to be applied to the element. Default is 'uploadbutton'. */
11
+ baseClass?: string;
12
+
13
+ /** Defaults to `false`. Set to `true` to enable multiple selection. */
14
+ multiple?: boolean;
15
+
16
+ method?: string;
17
+ uploadInProgressText?: string;
18
+
19
+ /** Defaults to `false`. Set to `true` to abort uploads if the button is destroyed (unmounted). */
20
+ abortOnDestroy?: boolean;
21
+
22
+ /** Defines file types that are accepted for upload. */
23
+ accept?: Cx.StringProp;
24
+
25
+ /** Name of the icon to be put on the left side of the button. */
26
+ icon?: Cx.StringProp;
27
+
28
+ onUploadStarting?: ((xhr: XMLHttpRequest, instance: any, file: File, formData: FormData) => boolean) | string;
29
+ onUploadComplete?: ((xhr: XMLHttpRequest, instance: any, file: File, formData: FormData) => void) | string;
30
+ onUploadProgress?: ((event: ProgressEvent, instance: any, file: File, formData: FormData) => void) | string;
31
+ onUploadError?: ((event: ProgressEvent, instance: any, file: File, formData: FormData) => void) | string;
32
+ }
33
+
34
+ export class UploadButton extends Cx.Widget<UploadButtonProps> {}
@@ -157,15 +157,15 @@ export class Grid extends Container {
157
157
  )
158
158
  row.hasResizableColumns = true;
159
159
 
160
- if (c.aggregate && (c.aggregateField || isDefined(c.aggregateValue))) {
160
+ if (c.aggregate && c.aggregateAlias && (c.aggregateField || isDefined(c.aggregateValue))) {
161
161
  aggregates[c.aggregateAlias] = {
162
162
  value: isDefined(c.aggregateValue)
163
163
  ? c.aggregateValue
164
164
  : isDefined(c.value)
165
- ? c.value
166
- : c.aggregateField
167
- ? { bind: this.recordName + "." + c.aggregateField }
168
- : null,
165
+ ? c.value
166
+ : c.aggregateField
167
+ ? { bind: this.recordName + "." + c.aggregateField }
168
+ : null,
169
169
  weight:
170
170
  c.weight != null
171
171
  ? c.weight
@@ -881,15 +881,22 @@ export class Grid extends Container {
881
881
  let v,
882
882
  c = ci.widget,
883
883
  colSpan,
884
- pad;
884
+ pad,
885
+ cls = "",
886
+ style = null;
885
887
  if (c.caption) {
886
888
  if (c.caption.children)
887
889
  v = <Cx widget={c.caption.children} store={store} parentInstance={instance} subscribe />;
888
- else v = c.caption.value(data);
890
+ else {
891
+ v = c.caption.value(data);
892
+ let fmt = c.caption.format(data);
893
+ if (fmt) v = Format.value(v, fmt);
894
+ }
889
895
  pad = c.caption.pad;
890
896
  colSpan = c.caption.colSpan;
891
897
  empty = false;
892
-
898
+ cls = CSS.expand(c.caption.class(data)) || "";
899
+ style = parseStyle(c.caption.style(data));
893
900
  if (c.caption.expand) {
894
901
  colSpan = 1;
895
902
  for (
@@ -903,19 +910,19 @@ export class Grid extends Container {
903
910
  }
904
911
 
905
912
  if (colSpan > 1) skip = colSpan - 1;
906
- } else if (c.aggregate && c.aggregateField && c.caption !== false) {
913
+ } else if (c.aggregate && c.aggregateAlias && c.caption !== false) {
907
914
  empty = false;
908
- v = group[c.aggregateField];
915
+ v = group[c.aggregateAlias];
909
916
  if (isString(ci.data.format)) v = Format.value(v, ci.data.format);
910
917
  }
911
918
 
912
- let cls = "";
919
+ if (cls) cls += " ";
913
920
  if (c.align) cls += CSS.state("aligned-" + c.align);
914
921
 
915
922
  if (pad !== false) cls += (cls ? " " : "") + CSS.state("pad");
916
923
 
917
924
  return (
918
- <td key={i} className={cls} colSpan={colSpan}>
925
+ <td key={i} className={cls} colSpan={colSpan} style={style}>
919
926
  {v}
920
927
  </td>
921
928
  );
@@ -986,9 +993,9 @@ export class Grid extends Container {
986
993
  }
987
994
 
988
995
  if (colSpan > 1) skip = colSpan - 1;
989
- } else if (c.aggregate && c.aggregateField && c.footer !== false) {
996
+ } else if (c.aggregate && c.aggregateAlias && c.footer !== false) {
990
997
  empty = false;
991
- v = group[c.aggregateField];
998
+ v = group[c.aggregateAlias];
992
999
  if (isString(ci.data.format)) v = Format.value(v, ci.data.format);
993
1000
  }
994
1001
 
@@ -3089,7 +3096,12 @@ class GridColumnHeader extends Widget {
3089
3096
  if (children) {
3090
3097
  delete this.caption.items;
3091
3098
  this.caption.children = Widget.create(children);
3092
- } else this.caption.value = getSelector(this.caption.value);
3099
+ } else {
3100
+ this.caption.value = getSelector(this.caption.value);
3101
+ this.caption.class = getSelector(this.caption.class);
3102
+ this.caption.style = getSelector(this.caption.style);
3103
+ this.caption.format = getSelector(this.caption.format);
3104
+ }
3093
3105
  }
3094
3106
 
3095
3107
  super.init();
@@ -1,124 +1,124 @@
1
- import { batchUpdates } from "../../ui/batchUpdates";
2
- import { getParentFrameBoundingClientRect } from "../../util/getParentFrameBoundingClientRect";
3
-
4
- export function captureMouse2(e, { onMouseMove, onMouseUp, onDblClick, captureData, cursor }) {
5
- let surface = document.createElement("div");
6
- surface.className = "cxb-mousecapture";
7
- surface.style.cursor = cursor || getComputedStyle(e.currentTarget).cursor;
8
-
9
- document.body.appendChild(surface);
10
-
11
- // In case when the event originates from an iframe,
12
- // we use that document as events do not bubble up. //
13
- let parentDocument = e.target.ownerDocument;
14
- let options = { capture: true };
15
-
16
- let active = true;
17
- parentDocument.addEventListener("mousemove", move, options);
18
- parentDocument.addEventListener("mouseup", end, options);
19
- if (onDblClick) parentDocument.addEventListener("dblclick", doubleClick), options;
20
-
21
- function tear() {
22
- if (surface == null) return;
23
- parentDocument.removeEventListener("mousemove", move, options);
24
- parentDocument.removeEventListener("mouseup", end, options);
25
- if (onDblClick) parentDocument.removeEventListener("dblclick", onDblClick, options);
26
- document.body.removeChild(surface);
27
- surface = null;
28
- }
29
-
30
- function doubleClick(e) {
31
- try {
32
- onDblClick(e);
33
- } finally {
34
- tear();
35
- }
36
- }
37
-
38
- e.stopPropagation();
39
-
40
- function move(e) {
41
- if (!active) {
42
- tear();
43
- return;
44
- }
45
-
46
- //if mouse moves double clicking is off
47
- onDblClick = null;
48
-
49
- batchUpdates(() => {
50
- if (onMouseMove) onMouseMove(e, captureData);
51
- e.stopPropagation();
52
- e.preventDefault(); //disable text selection
53
- });
54
- }
55
-
56
- function end(e) {
57
- active = false;
58
- batchUpdates(() => {
59
- // if (surface.releaseCapture)
60
- // surface.releaseCapture();
61
-
62
- if (!onDblClick) surface.style.display = "none";
63
- try {
64
- if (onMouseUp) onMouseUp(e, captureData);
65
- } finally {
66
- if (onDblClick) {
67
- //keep the surface a little longer to detect double clicks
68
- setTimeout(tear, 1500);
69
- } else tear();
70
- }
71
- });
72
- }
73
- }
74
-
75
- export function captureMouseOrTouch2(e, { onMouseMove, onMouseUp, onDblClick, captureData, cursor }) {
76
- if (e.type.indexOf("touch") == 0) {
77
- let el = e.currentTarget;
78
-
79
- let move = (e) => {
80
- batchUpdates(() => {
81
- if (onMouseMove) onMouseMove(e, captureData);
82
- e.preventDefault();
83
- });
84
- };
85
-
86
- let end = (e) => {
87
- batchUpdates(() => {
88
- el.removeEventListener("touchmove", move);
89
- el.removeEventListener("touchend", end);
90
-
91
- if (onMouseUp) onMouseUp(e);
92
-
93
- e.preventDefault();
94
- });
95
- };
96
-
97
- el.addEventListener("touchmove", move);
98
- el.addEventListener("touchend", end);
99
-
100
- e.stopPropagation();
101
- } else captureMouse2(e, { onMouseMove, onMouseUp, captureData, onDblClick, cursor });
102
- }
103
-
104
- export function captureMouse(e, onMouseMove, onMouseUp, captureData, cursor) {
105
- captureMouse2(e, {
106
- onMouseMove,
107
- onMouseUp,
108
- captureData,
109
- cursor,
110
- });
111
- }
112
-
113
- export function captureMouseOrTouch(e, onMouseMove, onMouseUp, captureData, cursor) {
114
- captureMouseOrTouch2(e, { onMouseMove, onMouseUp, captureData, cursor });
115
- }
116
-
117
- export function getCursorPos(e) {
118
- let p = (e.touches && e.touches[0]) || e;
119
- let offset = getParentFrameBoundingClientRect(e.target);
120
- return {
121
- clientX: p.clientX + offset.left,
122
- clientY: p.clientY + offset.top,
123
- };
124
- }
1
+ import { batchUpdates } from "../../ui/batchUpdates";
2
+ import { getParentFrameBoundingClientRect } from "../../util/getParentFrameBoundingClientRect";
3
+
4
+ export function captureMouse2(e, { onMouseMove, onMouseUp, onDblClick, captureData, cursor }) {
5
+ let surface = document.createElement("div");
6
+ surface.className = "cxb-mousecapture";
7
+ surface.style.cursor = cursor || getComputedStyle(e.currentTarget).cursor;
8
+
9
+ document.body.appendChild(surface);
10
+
11
+ // In case when the event originates from an iframe,
12
+ // we use that document as events do not bubble up. //
13
+ let parentDocument = e.target.ownerDocument;
14
+ let options = { capture: true };
15
+
16
+ let active = true;
17
+ parentDocument.addEventListener("mousemove", move, options);
18
+ parentDocument.addEventListener("mouseup", end, options);
19
+ if (onDblClick) parentDocument.addEventListener("dblclick", doubleClick), options;
20
+
21
+ function tear() {
22
+ if (surface == null) return;
23
+ parentDocument.removeEventListener("mousemove", move, options);
24
+ parentDocument.removeEventListener("mouseup", end, options);
25
+ if (onDblClick) parentDocument.removeEventListener("dblclick", onDblClick, options);
26
+ document.body.removeChild(surface);
27
+ surface = null;
28
+ }
29
+
30
+ function doubleClick(e) {
31
+ try {
32
+ onDblClick(e);
33
+ } finally {
34
+ tear();
35
+ }
36
+ }
37
+
38
+ e.stopPropagation();
39
+
40
+ function move(e) {
41
+ if (!active) {
42
+ tear();
43
+ return;
44
+ }
45
+
46
+ //if mouse moves double clicking is off
47
+ onDblClick = null;
48
+
49
+ batchUpdates(() => {
50
+ if (onMouseMove) onMouseMove(e, captureData);
51
+ e.stopPropagation();
52
+ e.preventDefault(); //disable text selection
53
+ });
54
+ }
55
+
56
+ function end(e) {
57
+ active = false;
58
+ batchUpdates(() => {
59
+ // if (surface.releaseCapture)
60
+ // surface.releaseCapture();
61
+
62
+ if (!onDblClick) surface.style.display = "none";
63
+ try {
64
+ if (onMouseUp) onMouseUp(e, captureData);
65
+ } finally {
66
+ if (onDblClick) {
67
+ //keep the surface a little longer to detect double clicks
68
+ setTimeout(tear, 1500);
69
+ } else tear();
70
+ }
71
+ });
72
+ }
73
+ }
74
+
75
+ export function captureMouseOrTouch2(e, { onMouseMove, onMouseUp, onDblClick, captureData, cursor }) {
76
+ if (e.type.indexOf("touch") == 0) {
77
+ let el = e.currentTarget;
78
+
79
+ let move = (e) => {
80
+ batchUpdates(() => {
81
+ if (onMouseMove) onMouseMove(e, captureData);
82
+ e.preventDefault();
83
+ });
84
+ };
85
+
86
+ let end = (e) => {
87
+ batchUpdates(() => {
88
+ el.removeEventListener("touchmove", move);
89
+ el.removeEventListener("touchend", end);
90
+
91
+ if (onMouseUp) onMouseUp(e);
92
+
93
+ e.preventDefault();
94
+ });
95
+ };
96
+
97
+ el.addEventListener("touchmove", move);
98
+ el.addEventListener("touchend", end);
99
+
100
+ e.stopPropagation();
101
+ } else captureMouse2(e, { onMouseMove, onMouseUp, captureData, onDblClick, cursor });
102
+ }
103
+
104
+ export function captureMouse(e, onMouseMove, onMouseUp, captureData, cursor) {
105
+ captureMouse2(e, {
106
+ onMouseMove,
107
+ onMouseUp,
108
+ captureData,
109
+ cursor,
110
+ });
111
+ }
112
+
113
+ export function captureMouseOrTouch(e, onMouseMove, onMouseUp, captureData, cursor) {
114
+ captureMouseOrTouch2(e, { onMouseMove, onMouseUp, captureData, cursor });
115
+ }
116
+
117
+ export function getCursorPos(e) {
118
+ let p = (e.touches && e.touches[0]) || e;
119
+ let offset = getParentFrameBoundingClientRect(e.target);
120
+ return {
121
+ clientX: p.clientX + offset.left,
122
+ clientY: p.clientY + offset.top,
123
+ };
124
+ }