cx 26.6.0 → 26.7.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 (69) hide show
  1. package/build/data/ExposedValueView.js +1 -1
  2. package/build/data/comparer.d.ts +6 -8
  3. package/build/data/comparer.d.ts.map +1 -1
  4. package/build/ui/Cx.d.ts +5 -0
  5. package/build/ui/Cx.d.ts.map +1 -1
  6. package/build/ui/Cx.js +34 -3
  7. package/build/ui/Prop.d.ts +1 -1
  8. package/build/ui/Prop.d.ts.map +1 -1
  9. package/build/ui/Restate.d.ts +6 -0
  10. package/build/ui/Restate.d.ts.map +1 -1
  11. package/build/ui/Restate.js +2 -1
  12. package/build/ui/adapter/ArrayAdapter.d.ts +4 -6
  13. package/build/ui/adapter/ArrayAdapter.d.ts.map +1 -1
  14. package/build/ui/adapter/GroupAdapter.d.ts +22 -2
  15. package/build/ui/adapter/GroupAdapter.d.ts.map +1 -1
  16. package/build/ui/adapter/GroupAdapter.js +80 -5
  17. package/build/widgets/DocumentTitle.d.ts.map +1 -1
  18. package/build/widgets/DocumentTitle.js +2 -0
  19. package/build/widgets/drag-drop/DragSource.d.ts +3 -2
  20. package/build/widgets/drag-drop/DragSource.d.ts.map +1 -1
  21. package/build/widgets/drag-drop/DropZone.d.ts +4 -4
  22. package/build/widgets/drag-drop/DropZone.d.ts.map +1 -1
  23. package/build/widgets/drag-drop/ops.d.ts +13 -2
  24. package/build/widgets/drag-drop/ops.d.ts.map +1 -1
  25. package/build/widgets/drag-drop/ops.js +36 -9
  26. package/build/widgets/form/NumberField.js +1 -0
  27. package/build/widgets/grid/Grid.d.ts +19 -3
  28. package/build/widgets/grid/Grid.d.ts.map +1 -1
  29. package/build/widgets/grid/Grid.js +2 -0
  30. package/build/widgets/grid/TreeNode.d.ts +2 -0
  31. package/build/widgets/grid/TreeNode.d.ts.map +1 -1
  32. package/build/widgets/overlay/captureMouse.d.ts +4 -4
  33. package/build/widgets/overlay/captureMouse.d.ts.map +1 -1
  34. package/build/widgets/overlay/captureMouse.js +8 -3
  35. package/dist/data.js +1 -1
  36. package/dist/manifest.js +866 -866
  37. package/dist/ui.js +130 -12
  38. package/dist/widgets.css +4 -0
  39. package/dist/widgets.js +43 -10
  40. package/package.json +1 -1
  41. package/src/data/ExposedValueView.spec.ts +57 -0
  42. package/src/data/ExposedValueView.ts +1 -1
  43. package/src/data/comparer.ts +6 -7
  44. package/src/ui/Cx.tsx +44 -3
  45. package/src/ui/DataProxy.ts +55 -55
  46. package/src/ui/Prop.ts +1 -1
  47. package/src/ui/Rescope.ts +50 -50
  48. package/src/ui/Restate.tsx +9 -0
  49. package/src/ui/adapter/ArrayAdapter.ts +6 -8
  50. package/src/ui/adapter/GroupAdapter.spec.ts +75 -0
  51. package/src/ui/adapter/GroupAdapter.ts +103 -10
  52. package/src/ui/exprHelpers.ts +96 -96
  53. package/src/widgets/DocumentTitle.ts +2 -0
  54. package/src/widgets/Sandbox.ts +104 -104
  55. package/src/widgets/drag-drop/DragSource.tsx +3 -3
  56. package/src/widgets/drag-drop/DropZone.tsx +5 -5
  57. package/src/widgets/drag-drop/ops.tsx +54 -12
  58. package/src/widgets/form/ColorField.scss +112 -112
  59. package/src/widgets/form/DateTimeField.scss +111 -111
  60. package/src/widgets/form/LookupField.maps.scss +26 -26
  61. package/src/widgets/form/MonthField.scss +113 -113
  62. package/src/widgets/form/NumberField.scss +4 -0
  63. package/src/widgets/form/NumberField.tsx +1 -0
  64. package/src/widgets/form/Select.scss +104 -104
  65. package/src/widgets/form/TextField.scss +66 -66
  66. package/src/widgets/grid/Grid.tsx +23 -2
  67. package/src/widgets/grid/TreeNode.tsx +3 -0
  68. package/src/widgets/nav/MenuItem.tsx +525 -525
  69. package/src/widgets/overlay/captureMouse.ts +14 -7
@@ -1,104 +1,104 @@
1
- @use "sass:math";
2
- @use "sass:map";
3
- @use "../variables" as *;
4
- @use "../maps" as *;
5
- @use "../../util/scss/add-rules.scss" as *;
6
- @use "../../util/scss/calc.scss" as *;
7
- @use "../../util/scss/clockwise.scss" as *;
8
- @use "../../util/scss/besm.scss" as *;
9
- @use "../../util/scss/include.scss" as *;
10
- @use "./Field.scss" as *;
11
-
12
- @mixin cx-select(
13
- $name: "select",
14
- $state-style-map: $cx-std-field-state-style-map,
15
- $placeholder: $cx-input-placeholder,
16
- $empty-text: $cx-empty-text,
17
- $width: $cx-default-input-width,
18
- $left-icon-state-style-map: $cx-input-left-icon-state-style-map,
19
- $clear-state-style-map: $cx-clear-state-style-map,
20
- $tool-state-style-map: $cx-input-right-icon-state-style-map,
21
- $icon-size: $cx-default-input-icon-size,
22
- $besm: $cx-besm
23
- ) {
24
- $block: map.get($besm, block);
25
- $element: map.get($besm, element);
26
- $state: map.get($besm, state);
27
- $mod: map.get($besm, mod);
28
-
29
- .#{$block}#{$name} {
30
- @include cxb-field($besm, $state-style-map: $state-style-map, $width: $width, $input: true);
31
-
32
- .#{$element}#{$name}-left-icon {
33
- pointer-events: none;
34
- @include cxe-field-button($besm, $left-icon-state-style-map);
35
- }
36
- }
37
-
38
- $padding: cx-get-state-rule($state-style-map, default, "padding");
39
-
40
- .#{$element}#{$name}-select {
41
- @include cxe-field-input(
42
- $besm,
43
- $state-style-map,
44
- $placeholder: $placeholder,
45
- $overrides: (
46
- padding: $cx-default-input-padding-top
47
- calc(#{$cx-default-input-padding-right} + #{$cx-default-clear-size} - #{$cx-default-input-padding-right})
48
- $cx-default-input-padding-bottom $cx-default-input-padding-left,
49
- -webkit-appearance: none,
50
- -moz-appearance: none,
51
- -ms-appearance: none,
52
- appearance: none
53
- )
54
- );
55
-
56
- .#{$state}icon > & {
57
- padding-left: cx-calc(cx-top($padding), $cx-default-input-left-tool-size, $cx-default-input-left-tool-spacing);
58
- }
59
-
60
- .#{$state}empty > & {
61
- @include cx-add-rules($placeholder);
62
- }
63
-
64
- &::-ms-expand {
65
- display: none;
66
- margin: 0;
67
- padding: 0;
68
- }
69
-
70
- option {
71
- background-color: $cx-default-dropdown-background-color;
72
- color: cx-get-state-rule($state-style-map, default, color);
73
- }
74
- }
75
-
76
- .#{$element}#{$name}-clear {
77
- @include cxe-field-button($besm, $clear-state-style-map);
78
- }
79
-
80
- .#{$element}#{$name}-placeholder {
81
- @include cx-add-rules($placeholder);
82
- }
83
-
84
- .#{$element}#{$name}-tool {
85
- pointer-events: none; //cannot call open-dropdown on native element
86
- @include cxe-field-button($besm, $tool-state-style-map);
87
-
88
- .#{$state}disabled > & {
89
- border-width: 0;
90
- @include cx-add-state-rules($state-style-map, disabled);
91
- }
92
- .#{$state}focus > & {
93
- @include cx-add-state-rules($tool-state-style-map, focus);
94
- }
95
- }
96
-
97
- .#{$element}#{$name}-icon {
98
- @include cxe-field-button-icon($besm, $icon-size);
99
- }
100
- }
101
-
102
- @if (cx-should-include("cx/widgets/Select")) {
103
- @include cx-select;
104
- }
1
+ @use "sass:math";
2
+ @use "sass:map";
3
+ @use "../variables" as *;
4
+ @use "../maps" as *;
5
+ @use "../../util/scss/add-rules.scss" as *;
6
+ @use "../../util/scss/calc.scss" as *;
7
+ @use "../../util/scss/clockwise.scss" as *;
8
+ @use "../../util/scss/besm.scss" as *;
9
+ @use "../../util/scss/include.scss" as *;
10
+ @use "./Field.scss" as *;
11
+
12
+ @mixin cx-select(
13
+ $name: "select",
14
+ $state-style-map: $cx-std-field-state-style-map,
15
+ $placeholder: $cx-input-placeholder,
16
+ $empty-text: $cx-empty-text,
17
+ $width: $cx-default-input-width,
18
+ $left-icon-state-style-map: $cx-input-left-icon-state-style-map,
19
+ $clear-state-style-map: $cx-clear-state-style-map,
20
+ $tool-state-style-map: $cx-input-right-icon-state-style-map,
21
+ $icon-size: $cx-default-input-icon-size,
22
+ $besm: $cx-besm
23
+ ) {
24
+ $block: map.get($besm, block);
25
+ $element: map.get($besm, element);
26
+ $state: map.get($besm, state);
27
+ $mod: map.get($besm, mod);
28
+
29
+ .#{$block}#{$name} {
30
+ @include cxb-field($besm, $state-style-map: $state-style-map, $width: $width, $input: true);
31
+
32
+ .#{$element}#{$name}-left-icon {
33
+ pointer-events: none;
34
+ @include cxe-field-button($besm, $left-icon-state-style-map);
35
+ }
36
+ }
37
+
38
+ $padding: cx-get-state-rule($state-style-map, default, "padding");
39
+
40
+ .#{$element}#{$name}-select {
41
+ @include cxe-field-input(
42
+ $besm,
43
+ $state-style-map,
44
+ $placeholder: $placeholder,
45
+ $overrides: (
46
+ padding: $cx-default-input-padding-top
47
+ calc(#{$cx-default-input-padding-right} + #{$cx-default-clear-size} - #{$cx-default-input-padding-right})
48
+ $cx-default-input-padding-bottom $cx-default-input-padding-left,
49
+ -webkit-appearance: none,
50
+ -moz-appearance: none,
51
+ -ms-appearance: none,
52
+ appearance: none
53
+ )
54
+ );
55
+
56
+ .#{$state}icon > & {
57
+ padding-left: cx-calc(cx-top($padding), $cx-default-input-left-tool-size, $cx-default-input-left-tool-spacing);
58
+ }
59
+
60
+ .#{$state}empty > & {
61
+ @include cx-add-rules($placeholder);
62
+ }
63
+
64
+ &::-ms-expand {
65
+ display: none;
66
+ margin: 0;
67
+ padding: 0;
68
+ }
69
+
70
+ option {
71
+ background-color: $cx-default-dropdown-background-color;
72
+ color: cx-get-state-rule($state-style-map, default, color);
73
+ }
74
+ }
75
+
76
+ .#{$element}#{$name}-clear {
77
+ @include cxe-field-button($besm, $clear-state-style-map);
78
+ }
79
+
80
+ .#{$element}#{$name}-placeholder {
81
+ @include cx-add-rules($placeholder);
82
+ }
83
+
84
+ .#{$element}#{$name}-tool {
85
+ pointer-events: none; //cannot call open-dropdown on native element
86
+ @include cxe-field-button($besm, $tool-state-style-map);
87
+
88
+ .#{$state}disabled > & {
89
+ border-width: 0;
90
+ @include cx-add-state-rules($state-style-map, disabled);
91
+ }
92
+ .#{$state}focus > & {
93
+ @include cx-add-state-rules($tool-state-style-map, focus);
94
+ }
95
+ }
96
+
97
+ .#{$element}#{$name}-icon {
98
+ @include cxe-field-button-icon($besm, $icon-size);
99
+ }
100
+ }
101
+
102
+ @if (cx-should-include("cx/widgets/Select")) {
103
+ @include cx-select;
104
+ }
@@ -1,66 +1,66 @@
1
- @use "sass:math";
2
- @use "sass:map";
3
- @use "../variables" as *;
4
- @use "../maps" as *;
5
- @use "../../util/scss/add-rules.scss" as *;
6
- @use "../../util/scss/calc.scss" as *;
7
- @use "../../util/scss/clockwise.scss" as *;
8
- @use "../../util/scss/besm.scss" as *;
9
- @use "../../util/scss/include.scss" as *;
10
- @use "./Field.scss" as *;
11
-
12
- @mixin cx-textfield(
13
- $name: "textfield",
14
- $state-style-map: $cx-std-field-state-style-map,
15
- $placeholder: $cx-input-placeholder,
16
- $empty-text: $cx-empty-text,
17
- $left-icon-state-style-map: $cx-input-left-icon-state-style-map,
18
- $clear-state-style-map: $cx-clear-state-style-map,
19
- $icon-size: $cx-default-input-icon-size,
20
- $width: $cx-default-input-width,
21
- $besm: $cx-besm
22
- ) {
23
- $block: map.get($besm, block);
24
- $element: map.get($besm, element);
25
- $state: map.get($besm, state);
26
- $mod: map.get($besm, mod);
27
-
28
- .#{$block}#{$name} {
29
- @include cxb-field($besm, $state-style-map, $width: $width, $input: true);
30
- }
31
-
32
- $padding: cx-get-state-rule($state-style-map, default, "padding");
33
-
34
- .#{$element}#{$name}-input {
35
- @include cxe-field-input($besm, $state-style-map, $placeholder: $placeholder);
36
-
37
- .#{$state}icon > & {
38
- padding-left: cx-calc(cx-top($padding), $cx-default-input-left-tool-size, $cx-default-input-left-tool-spacing);
39
- }
40
-
41
- .#{$state}clear > & {
42
- padding-right: cx-calc(cx-top($padding), $cx-default-clear-size, $cx-default-clear-spacing);
43
- }
44
- }
45
-
46
- .#{$element}#{$name}-left-icon {
47
- pointer-events: none;
48
- @include cxe-field-button($besm, $left-icon-state-style-map);
49
- }
50
-
51
- .#{$element}#{$name}-clear {
52
- @include cxe-field-button($besm, $clear-state-style-map);
53
- }
54
-
55
- .#{$element}#{$name}-icon {
56
- @include cxe-field-button-icon($besm, $icon-size);
57
- }
58
-
59
- .#{$element}#{$name}-empty-text {
60
- @include cxe-field-empty-text($empty-text);
61
- }
62
- }
63
-
64
- @if (cx-should-include("cx/widgets/TextField")) {
65
- @include cx-textfield();
66
- }
1
+ @use "sass:math";
2
+ @use "sass:map";
3
+ @use "../variables" as *;
4
+ @use "../maps" as *;
5
+ @use "../../util/scss/add-rules.scss" as *;
6
+ @use "../../util/scss/calc.scss" as *;
7
+ @use "../../util/scss/clockwise.scss" as *;
8
+ @use "../../util/scss/besm.scss" as *;
9
+ @use "../../util/scss/include.scss" as *;
10
+ @use "./Field.scss" as *;
11
+
12
+ @mixin cx-textfield(
13
+ $name: "textfield",
14
+ $state-style-map: $cx-std-field-state-style-map,
15
+ $placeholder: $cx-input-placeholder,
16
+ $empty-text: $cx-empty-text,
17
+ $left-icon-state-style-map: $cx-input-left-icon-state-style-map,
18
+ $clear-state-style-map: $cx-clear-state-style-map,
19
+ $icon-size: $cx-default-input-icon-size,
20
+ $width: $cx-default-input-width,
21
+ $besm: $cx-besm
22
+ ) {
23
+ $block: map.get($besm, block);
24
+ $element: map.get($besm, element);
25
+ $state: map.get($besm, state);
26
+ $mod: map.get($besm, mod);
27
+
28
+ .#{$block}#{$name} {
29
+ @include cxb-field($besm, $state-style-map, $width: $width, $input: true);
30
+ }
31
+
32
+ $padding: cx-get-state-rule($state-style-map, default, "padding");
33
+
34
+ .#{$element}#{$name}-input {
35
+ @include cxe-field-input($besm, $state-style-map, $placeholder: $placeholder);
36
+
37
+ .#{$state}icon > & {
38
+ padding-left: cx-calc(cx-top($padding), $cx-default-input-left-tool-size, $cx-default-input-left-tool-spacing);
39
+ }
40
+
41
+ .#{$state}clear > & {
42
+ padding-right: cx-calc(cx-top($padding), $cx-default-clear-size, $cx-default-clear-spacing);
43
+ }
44
+ }
45
+
46
+ .#{$element}#{$name}-left-icon {
47
+ pointer-events: none;
48
+ @include cxe-field-button($besm, $left-icon-state-style-map);
49
+ }
50
+
51
+ .#{$element}#{$name}-clear {
52
+ @include cxe-field-button($besm, $clear-state-style-map);
53
+ }
54
+
55
+ .#{$element}#{$name}-icon {
56
+ @include cxe-field-button-icon($besm, $icon-size);
57
+ }
58
+
59
+ .#{$element}#{$name}-empty-text {
60
+ @include cxe-field-empty-text($empty-text);
61
+ }
62
+ }
63
+
64
+ @if (cx-should-include("cx/widgets/TextField")) {
65
+ @include cx-textfield();
66
+ }
@@ -23,6 +23,7 @@ import {
23
23
  NumberProp,
24
24
  Prop,
25
25
  RecordAlias,
26
+ Sorter,
26
27
  SortDirection,
27
28
  SortersProp,
28
29
  StringProp,
@@ -62,6 +63,7 @@ import {
62
63
  ddMouseDown,
63
64
  DragDropOperationContext,
64
65
  DragEvent,
66
+ DragEndEvent,
65
67
  initiateDragDrop,
66
68
  registerDropZone,
67
69
  } from "../drag-drop/ops";
@@ -165,6 +167,15 @@ export interface GridGroupingConfig<T> {
165
167
  name?: StringProp;
166
168
  text?: StringProp;
167
169
  comparer?: (a: GroupingResult<T>, b: GroupingResult<T>) => number;
170
+ /**
171
+ * Sort groups by a single field resolved against the group's key, aggregates and name.
172
+ * Use an aggregate alias to sort by an aggregate, or a key field to sort by key.
173
+ */
174
+ sortField?: string;
175
+ /** Sort direction used together with `sortField`. Defaults to `"ASC"`. */
176
+ sortDirection?: SortDirection;
177
+ /** Multi-field group sorting. Each sorter's `field` is resolved against the group's key, aggregates and name. */
178
+ sorters?: Sorter[];
168
179
  }
169
180
 
170
181
  export interface GridColumnHeaderConfig {
@@ -390,7 +401,7 @@ export interface GridConfig<T = any> extends StyledContainerConfig {
390
401
  onDrop?: string | ((e: GridDragEvent<T>, instance: Instance) => void);
391
402
  onDropTest?: string | ((e: DragEvent, instance: Instance) => boolean);
392
403
  onDragStart?: string | ((e: DragEvent, instance: Instance) => void);
393
- onDragEnd?: string | ((e: DragEvent, instance: Instance) => void);
404
+ onDragEnd?: string | ((e: DragEndEvent, instance: Instance) => void);
394
405
  onDragOver?: string | ((e: GridDragEvent<T>, instance: Instance) => void | boolean);
395
406
 
396
407
  onRowDropTest?: string | ((e: DragEvent, instance: Instance) => boolean);
@@ -502,6 +513,13 @@ export interface GridConfig<T = any> extends StyledContainerConfig {
502
513
 
503
514
  /** When enabled, groups are shown in the same order as the source records. */
504
515
  preserveGroupOrder?: boolean;
516
+
517
+ /**
518
+ * When enabled, sorting by a column header also reorders groups. The active sort field is resolved
519
+ * against each group's key fields, aggregates and name, so it works for both grouping columns and
520
+ * aggregate columns. Ignored when `preserveGroupOrder` is set.
521
+ */
522
+ sortGroups?: boolean;
505
523
  }
506
524
 
507
525
  export interface GridCellInfo {
@@ -635,6 +653,7 @@ export class Grid<T = unknown> extends ContainerBase<GridConfig<T>, GridInstance
635
653
  declare onCreateIsRecordDraggable?: any;
636
654
  declare onRef?: any;
637
655
  declare preserveGroupOrder: boolean;
656
+ declare sortGroups: boolean;
638
657
  declare styled: boolean;
639
658
  declare selectable?: boolean;
640
659
  declare recordsAccessor: any;
@@ -844,6 +863,7 @@ export class Grid<T = unknown> extends ContainerBase<GridConfig<T>, GridInstance
844
863
  sortOptions: this.sortOptions,
845
864
  groupings: grouping,
846
865
  preserveOrder: this.preserveGroupOrder,
866
+ sortGroupsBySorters: this.sortGroups,
847
867
  },
848
868
  this.dataAdapter,
849
869
  );
@@ -1903,6 +1923,7 @@ Grid.prototype.hoverChannel = "default";
1903
1923
  Grid.prototype.focusable = null; // automatically resolved
1904
1924
  Grid.prototype.allowsFileDrops = false;
1905
1925
  Grid.prototype.preserveGroupOrder = false;
1926
+ Grid.prototype.sortGroups = false;
1906
1927
 
1907
1928
  Widget.alias("grid", Grid);
1908
1929
  Localization.registerPrototype("cx/widgets/Grid", Grid);
@@ -2851,7 +2872,7 @@ class GridComponent extends VDOM.Component<GridComponentProps, GridComponentStat
2851
2872
  return (grid || row || column) && { grid, row, column };
2852
2873
  }
2853
2874
 
2854
- onDragEnd(e: DragEvent) {
2875
+ onDragEnd(e: DragEndEvent) {
2855
2876
  this.setState({
2856
2877
  dropTarget: null,
2857
2878
  dropInsertionIndex: null,
@@ -41,6 +41,9 @@ export interface TreeNodeConfig extends StyledContainerConfig {
41
41
  /** Icon for folder. */
42
42
  folderIcon?: StringProp;
43
43
 
44
+ /** Icon used for the expand/collapse arrow. Defaults to `drop-down`. */
45
+ arrowIcon?: StringProp;
46
+
44
47
  /** Set to `true` to hide the icon. */
45
48
  hideIcon?: boolean;
46
49