cx 26.4.4 → 26.5.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/charts/axis/Axis.d.ts +8 -0
  2. package/build/charts/axis/Axis.d.ts.map +1 -1
  3. package/build/charts/axis/Axis.js +18 -1
  4. package/build/charts/axis/TimeAxis.js +1 -0
  5. package/build/ui/Format.d.ts.map +1 -1
  6. package/build/ui/Format.js +26 -2
  7. package/build/util/Format.d.ts.map +1 -1
  8. package/build/util/Format.js +6 -0
  9. package/build/util/date/dateQuarter.d.ts +7 -0
  10. package/build/util/date/dateQuarter.d.ts.map +1 -0
  11. package/build/util/date/dateQuarter.js +8 -0
  12. package/build/util/date/dayBefore.d.ts +12 -0
  13. package/build/util/date/dayBefore.d.ts.map +1 -0
  14. package/build/util/date/dayBefore.js +15 -0
  15. package/build/util/date/index.d.ts +2 -0
  16. package/build/util/date/index.d.ts.map +1 -1
  17. package/build/util/date/index.js +2 -0
  18. package/build/widgets/form/DateTimePicker.d.ts.map +1 -1
  19. package/build/widgets/form/DateTimePicker.js +53 -31
  20. package/build/widgets/form/Field.d.ts.map +1 -1
  21. package/build/widgets/form/Field.js +2 -1
  22. package/build/widgets/form/Wheel.d.ts +8 -0
  23. package/build/widgets/form/Wheel.d.ts.map +1 -1
  24. package/build/widgets/form/Wheel.js +30 -7
  25. package/build/widgets/grid/Grid.d.ts +1 -1
  26. package/build/widgets/grid/Grid.d.ts.map +1 -1
  27. package/dist/charts.css +6 -0
  28. package/dist/charts.js +18 -1
  29. package/dist/manifest.js +787 -778
  30. package/dist/ui.js +33 -1
  31. package/dist/util.js +32 -0
  32. package/dist/widgets.js +225 -173
  33. package/package.json +1 -1
  34. package/src/charts/BarGraph.scss +31 -31
  35. package/src/charts/Legend.scss +57 -57
  36. package/src/charts/LegendEntry.scss +35 -35
  37. package/src/charts/LineGraph.scss +28 -28
  38. package/src/charts/RangeMarker.scss +3 -0
  39. package/src/charts/axis/Axis.tsx +31 -1
  40. package/src/charts/axis/TimeAxis.tsx +1 -0
  41. package/src/charts/helpers/SnapPointFinder.ts +136 -136
  42. package/src/charts/helpers/ValueAtFinder.ts +72 -72
  43. package/src/charts/index.scss +1 -0
  44. package/src/data/AugmentedViewBase.ts +89 -89
  45. package/src/data/View.ts +301 -301
  46. package/src/data/createAccessorModelProxy.ts +66 -66
  47. package/src/ui/Format.spec.ts +32 -0
  48. package/src/ui/Format.ts +27 -2
  49. package/src/ui/Repeater.spec.tsx +181 -181
  50. package/src/util/Format.spec.ts +11 -0
  51. package/src/util/Format.ts +7 -0
  52. package/src/util/date/dateQuarter.ts +8 -0
  53. package/src/util/date/dayBefore.ts +15 -0
  54. package/src/util/date/index.ts +2 -0
  55. package/src/util/scss/include.scss +69 -69
  56. package/src/widgets/Button.maps.scss +103 -103
  57. package/src/widgets/form/Calendar.tsx +772 -772
  58. package/src/widgets/form/DateTimePicker.tsx +453 -392
  59. package/src/widgets/form/Field.tsx +2 -1
  60. package/src/widgets/form/ValidationGroup.spec.tsx +30 -1
  61. package/src/widgets/form/Wheel.tsx +36 -7
  62. package/src/widgets/grid/Grid.scss +657 -657
  63. package/src/widgets/grid/Grid.tsx +1 -1
  64. package/src/widgets/grid/variables.scss +47 -47
  65. package/src/widgets/index.ts +63 -63
  66. package/src/widgets/nav/MenuItem.scss +150 -150
  67. package/src/widgets/nav/Tab.ts +122 -122
  68. package/src/widgets/overlay/Overlay.tsx +1029 -1029
  69. package/src/widgets/variables.scss +61 -61
@@ -312,6 +312,7 @@ export class Field<
312
312
  data._readOnly = data.readOnly;
313
313
  data._viewMode = data.mode === "view" || data.viewMode;
314
314
  data._tabOnEnterKey = data.tabOnEnterKey;
315
+ data._visited = data.visited;
315
316
  data.validationValue = this.getValidationValue(data);
316
317
  instance.parentDisabled = context.parentDisabled;
317
318
  instance.parentReadOnly = context.parentReadOnly;
@@ -366,7 +367,7 @@ export class Field<
366
367
  );
367
368
  data.visited = coalesce(
368
369
  context.parentStrict ? context.parentVisited : null,
369
- data.visited,
370
+ data._visited,
370
371
  context.parentVisited,
371
372
  );
372
373
 
@@ -1,8 +1,9 @@
1
1
  import { Store } from "../../data/Store";
2
2
  import { ValidationGroup } from "./ValidationGroup";
3
3
  import { Validator } from "./Validator";
4
+ import { TextField } from "./TextField";
4
5
  import { bind } from "../../ui/bind";
5
- import { createTestRenderer } from "../../util/test/createTestRenderer";
6
+ import { createTestRenderer, act } from "../../util/test/createTestRenderer";
6
7
 
7
8
  import assert from "assert";
8
9
 
@@ -107,6 +108,34 @@ describe("ValidationGroup", () => {
107
108
  assert(visited);
108
109
  });
109
110
 
111
+ it("visited flag changes are propagated to fields after being initialized to false", async () => {
112
+ let widget = (
113
+ <cx>
114
+ <ValidationGroup errors={bind("errors")} visited={bind("form.visited")}>
115
+ <TextField required value={bind("value1")} />
116
+ </ValidationGroup>
117
+ </cx>
118
+ );
119
+
120
+ let store = new Store();
121
+ //initializing the bound value to false used to shadow later updates
122
+ store.set("form.visited", false);
123
+
124
+ const component = await createTestRenderer(store, widget);
125
+
126
+ let errors = store.get("errors");
127
+ assert.equal(errors.length, 1);
128
+ assert.equal(errors[0].visited, false);
129
+
130
+ await act(async () => {
131
+ store.set("form.visited", true);
132
+ });
133
+
134
+ errors = store.get("errors");
135
+ assert.equal(errors.length, 1);
136
+ assert.equal(errors[0].visited, true);
137
+ });
138
+
110
139
  it("disabled flag can be overruled by the field props", async () => {
111
140
  let widget = (
112
141
  <cx>
@@ -65,6 +65,10 @@ Wheel.prototype.baseClass = "wheel";
65
65
  Wheel.prototype.size = 3;
66
66
  Wheel.prototype.styled = true;
67
67
 
68
+ /** A cyclic wheel renders its option list this many times, leaving scroll
69
+ * headroom on both sides of the centre copy. */
70
+ export const WHEEL_BUFFER_COPIES = 3;
71
+
68
72
  export interface WheelComponentProps {
69
73
  size: number;
70
74
  children: React.ReactNode[];
@@ -74,6 +78,11 @@ export interface WheelComponentProps {
74
78
  className?: string;
75
79
  style?: React.CSSProperties;
76
80
  index?: number;
81
+ /** Set to render the option list as an endlessly scrolling wheel. The list
82
+ * is rendered `WHEEL_BUFFER_COPIES` times and the wheel snaps to whichever
83
+ * copy of the selected value is nearest its current position, so a wrap
84
+ * scrolls seamlessly into the adjacent identical copy. */
85
+ cycle?: boolean;
77
86
  onChange: (newIndex: number) => void;
78
87
  onPipeKeyDown?: (fn: (e: React.KeyboardEvent) => void) => void;
79
88
  onMouseDown?: () => void;
@@ -109,23 +118,30 @@ export class WheelComponent extends VDOM.Component<WheelComponentProps, WheelCom
109
118
  scrollRef: (el: HTMLDivElement | null) => void;
110
119
 
111
120
  render(): React.ReactNode {
112
- let { size, children, CSS, baseClass, active, className, style, onMouseDown } = this.props;
121
+ let { size, children, CSS, baseClass, active, className, style, onMouseDown, cycle } = this.props;
113
122
  let optionClass = CSS.element(baseClass, "option");
114
123
  let dummyClass = CSS.element(baseClass, "option", { dummy: true });
115
124
 
125
+ // A cyclic wheel repeats the option list so it can scroll past either end.
126
+ let options = children;
127
+ if (cycle) {
128
+ options = [];
129
+ for (let i = 0; i < WHEEL_BUFFER_COPIES; i++) options.push(...children);
130
+ }
131
+
116
132
  let tpad = [],
117
133
  bpad = [],
118
134
  padSize = 0;
119
135
 
120
136
  for (let i = 0; i < (size - 1) / 2; i++) {
121
- tpad.push({ key: -1 - i, child: children[0], cls: dummyClass });
122
- bpad.push({ key: -100 - i, child: children[0], cls: dummyClass });
137
+ tpad.push({ key: -1 - i, child: options[0], cls: dummyClass });
138
+ bpad.push({ key: -100 - i, child: options[0], cls: dummyClass });
123
139
  padSize++;
124
140
  }
125
141
 
126
142
  let displayedOptions = [
127
143
  ...tpad,
128
- ...children.map((c, i) => ({
144
+ ...options.map((c, i) => ({
129
145
  key: i,
130
146
  child: c,
131
147
  cls: optionClass,
@@ -228,7 +244,19 @@ export class WheelComponent extends VDOM.Component<WheelComponentProps, WheelCom
228
244
  }
229
245
 
230
246
  UNSAFE_componentWillReceiveProps(props: WheelComponentProps): void {
231
- this.index = props.index || 0;
247
+ let newIndex = props.index || 0;
248
+ // A cyclic wheel renders the option list several times, so the same value
249
+ // appears in several copies. Snap to the copy nearest the wheel's current
250
+ // position rather than the one `props.index` names — a wrap then scrolls
251
+ // one item into the adjacent (identical) copy with no jump, instead of
252
+ // animating all the way back to the centre copy.
253
+ if (props.cycle) {
254
+ let period = props.children.length;
255
+ let value = ((newIndex % period) + period) % period;
256
+ newIndex = value + period * Math.round((this.index - value) / period);
257
+ newIndex = Math.max(0, Math.min(period * WHEEL_BUFFER_COPIES - 1, newIndex));
258
+ }
259
+ this.index = newIndex;
232
260
  this.scrollTo();
233
261
  }
234
262
 
@@ -272,8 +300,9 @@ export class WheelComponent extends VDOM.Component<WheelComponentProps, WheelCom
272
300
  }
273
301
 
274
302
  select(newIndex: number): void {
275
- let { children } = this.props;
276
- newIndex = Math.max(0, Math.min(children.length - 1, newIndex));
303
+ let { children, cycle } = this.props;
304
+ let length = children.length * (cycle ? WHEEL_BUFFER_COPIES : 1);
305
+ newIndex = Math.max(0, Math.min(length - 1, newIndex));
277
306
  if (this.index !== newIndex) {
278
307
  this.index = newIndex;
279
308
  this.props.onChange(newIndex);