cx 26.2.1 → 26.2.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 (324) hide show
  1. package/build/charts/Chart.d.ts.map +1 -1
  2. package/build/charts/Chart.js +5 -4
  3. package/build/charts/ColumnBarBase.d.ts +3 -3
  4. package/build/charts/ColumnBarBase.d.ts.map +1 -1
  5. package/build/charts/ColumnBarBase.js +1 -1
  6. package/build/charts/Legend.d.ts.map +1 -1
  7. package/build/charts/Legend.js +11 -4
  8. package/build/charts/Marker.d.ts +3 -3
  9. package/build/charts/Marker.d.ts.map +1 -1
  10. package/build/charts/MarkerLine.d.ts +7 -7
  11. package/build/charts/MarkerLine.d.ts.map +1 -1
  12. package/build/charts/MarkerLine.js +14 -10
  13. package/build/charts/PieChart.d.ts +4 -4
  14. package/build/charts/PieChart.d.ts.map +1 -1
  15. package/build/charts/PieChart.js +36 -14
  16. package/build/charts/PieLabel.d.ts.map +1 -1
  17. package/build/charts/PieLabel.js +2 -1
  18. package/build/charts/RangeMarker.d.ts +3 -3
  19. package/build/charts/RangeMarker.d.ts.map +1 -1
  20. package/build/charts/RangeMarker.js +1 -1
  21. package/build/charts/axis/TimeAxis.d.ts +3 -3
  22. package/build/charts/axis/TimeAxis.d.ts.map +1 -1
  23. package/build/charts/axis/TimeAxis.js +70 -21
  24. package/build/charts/helpers/ValueAtFinder.d.ts +1 -1
  25. package/build/charts/helpers/ValueAtFinder.d.ts.map +1 -1
  26. package/build/charts/helpers/ValueAtFinder.js +5 -2
  27. package/build/data/StructuredSelector.js +3 -4
  28. package/build/data/createAccessorModelProxy.d.ts +6 -11
  29. package/build/data/createAccessorModelProxy.d.ts.map +1 -1
  30. package/build/data/createAccessorModelProxy.js +1 -3
  31. package/build/svg/Ellipse.d.ts +5 -4
  32. package/build/svg/Ellipse.d.ts.map +1 -1
  33. package/build/svg/Ellipse.js +9 -6
  34. package/build/svg/Line.d.ts +1 -0
  35. package/build/svg/Line.d.ts.map +1 -1
  36. package/build/svg/Line.js +4 -1
  37. package/build/svg/Text.d.ts +12 -6
  38. package/build/svg/Text.d.ts.map +1 -1
  39. package/build/svg/Text.js +12 -4
  40. package/build/ui/Controller.d.ts +2 -0
  41. package/build/ui/Controller.d.ts.map +1 -1
  42. package/build/ui/Controller.js +3 -0
  43. package/build/ui/HoverSync.d.ts.map +1 -1
  44. package/build/ui/HoverSync.js +7 -2
  45. package/build/ui/Prop.d.ts +1 -1
  46. package/build/ui/Prop.d.ts.map +1 -1
  47. package/build/ui/Text.d.ts +3 -3
  48. package/build/ui/Text.d.ts.map +1 -1
  49. package/build/ui/Text.js +5 -5
  50. package/build/ui/adapter/GroupAdapter.d.ts.map +1 -1
  51. package/build/ui/adapter/GroupAdapter.js +20 -10
  52. package/build/ui/app/History.js +1 -1
  53. package/build/widgets/List.d.ts.map +1 -1
  54. package/build/widgets/List.js +6 -7
  55. package/build/widgets/drag-drop/DropZone.d.ts +3 -3
  56. package/build/widgets/drag-drop/DropZone.d.ts.map +1 -1
  57. package/build/widgets/form/Calendar.d.ts.map +1 -1
  58. package/build/widgets/form/Calendar.js +30 -11
  59. package/build/widgets/form/ColorField.d.ts.map +1 -1
  60. package/build/widgets/form/ColorField.js +16 -7
  61. package/build/widgets/form/DateTimeField.d.ts.map +1 -1
  62. package/build/widgets/form/DateTimeField.js +23 -10
  63. package/build/widgets/form/Field.d.ts +2 -0
  64. package/build/widgets/form/Field.d.ts.map +1 -1
  65. package/build/widgets/form/Field.js +11 -5
  66. package/build/widgets/form/LookupField.d.ts +1 -1
  67. package/build/widgets/form/LookupField.d.ts.map +1 -1
  68. package/build/widgets/form/LookupField.js +6 -6
  69. package/build/widgets/form/MonthField.d.ts.map +1 -1
  70. package/build/widgets/form/MonthField.js +15 -7
  71. package/build/widgets/form/MonthPicker.d.ts +1 -2
  72. package/build/widgets/form/MonthPicker.d.ts.map +1 -1
  73. package/build/widgets/form/MonthPicker.js +84 -41
  74. package/build/widgets/form/NumberField.d.ts +2 -0
  75. package/build/widgets/form/NumberField.d.ts.map +1 -1
  76. package/build/widgets/form/NumberField.js +45 -15
  77. package/build/widgets/form/TextField.d.ts +1 -9
  78. package/build/widgets/form/TextField.d.ts.map +1 -1
  79. package/build/widgets/form/TextField.js +1 -1
  80. package/build/widgets/grid/Grid.d.ts +2 -2
  81. package/build/widgets/grid/Grid.d.ts.map +1 -1
  82. package/build/widgets/grid/Grid.js +9 -4
  83. package/build/widgets/grid/Pagination.d.ts.map +1 -1
  84. package/build/widgets/grid/Pagination.js +4 -4
  85. package/build/widgets/grid/TreeNode.d.ts.map +1 -1
  86. package/build/widgets/grid/TreeNode.js +10 -2
  87. package/build/widgets/icons/folder.d.ts.map +1 -1
  88. package/build/widgets/icons/folder.js +1 -0
  89. package/build/widgets/icons/forward.d.ts.map +1 -1
  90. package/build/widgets/icons/forward.js +4 -3
  91. package/build/widgets/icons/loading.d.ts.map +1 -1
  92. package/build/widgets/icons/loading.js +6 -5
  93. package/build/widgets/icons/square.d.ts.map +1 -1
  94. package/build/widgets/icons/square.js +3 -3
  95. package/build/widgets/index.d.ts +3 -1
  96. package/build/widgets/index.d.ts.map +1 -1
  97. package/build/widgets/index.js +3 -1
  98. package/build/widgets/overlay/ContextMenu.d.ts.map +1 -1
  99. package/build/widgets/overlay/ContextMenu.js +2 -0
  100. package/build/widgets/overlay/Dropdown.d.ts +2 -1
  101. package/build/widgets/overlay/Dropdown.d.ts.map +1 -1
  102. package/build/widgets/overlay/Dropdown.js +75 -20
  103. package/build/widgets/overlay/MsgBox.d.ts +1 -0
  104. package/build/widgets/overlay/MsgBox.d.ts.map +1 -1
  105. package/build/widgets/overlay/MsgBox.js +2 -2
  106. package/build/widgets/overlay/Overlay.d.ts +32 -2
  107. package/build/widgets/overlay/Overlay.d.ts.map +1 -1
  108. package/build/widgets/overlay/Overlay.js +47 -16
  109. package/build/widgets/overlay/Toast.d.ts +1 -1
  110. package/build/widgets/overlay/Toast.d.ts.map +1 -1
  111. package/build/widgets/overlay/Toast.js +4 -1
  112. package/build/widgets/overlay/Tooltip.d.ts +6 -0
  113. package/build/widgets/overlay/Tooltip.d.ts.map +1 -1
  114. package/build/widgets/overlay/Tooltip.js +24 -9
  115. package/build/widgets/overlay/Window.d.ts.map +1 -1
  116. package/build/widgets/overlay/Window.js +24 -9
  117. package/dist/charts.css +325 -272
  118. package/dist/charts.js +11 -5
  119. package/dist/data.js +2 -2
  120. package/dist/manifest.js +892 -880
  121. package/dist/svg.css +14 -8
  122. package/dist/svg.js +9 -1
  123. package/dist/ui.js +29 -16
  124. package/dist/widgets.css +997 -294
  125. package/dist/widgets.js +317 -121
  126. package/package.json +1 -1
  127. package/src/charts/Bar.scss +13 -10
  128. package/src/charts/BarGraph.scss +31 -29
  129. package/src/charts/BubbleGraph.scss +11 -8
  130. package/src/charts/Chart.ts +5 -3
  131. package/src/charts/Column.scss +13 -10
  132. package/src/charts/ColumnBarBase.tsx +255 -230
  133. package/src/charts/ColumnGraph.scss +13 -11
  134. package/src/charts/Gridlines.scss +10 -8
  135. package/src/charts/Legend.scss +57 -50
  136. package/src/charts/Legend.tsx +257 -213
  137. package/src/charts/LegendEntry.scss +35 -29
  138. package/src/charts/LineGraph.scss +28 -25
  139. package/src/charts/Marker.scss +12 -10
  140. package/src/charts/Marker.tsx +3 -2
  141. package/src/charts/MarkerLine.scss +11 -8
  142. package/src/charts/MarkerLine.tsx +196 -177
  143. package/src/charts/PieChart.scss +12 -9
  144. package/src/charts/PieChart.tsx +717 -591
  145. package/src/charts/PieLabel.tsx +99 -81
  146. package/src/charts/Range.scss +11 -8
  147. package/src/charts/RangeMarker.tsx +204 -187
  148. package/src/charts/ScatterGraph.scss +12 -9
  149. package/src/charts/axis/Axis.scss +6 -5
  150. package/src/charts/axis/CategoryAxis.scss +10 -8
  151. package/src/charts/axis/NumericAxis.scss +9 -6
  152. package/src/charts/axis/TimeAxis.scss +9 -6
  153. package/src/charts/axis/TimeAxis.tsx +753 -637
  154. package/src/charts/axis/index.scss +4 -5
  155. package/src/charts/axis/variables.scss +4 -2
  156. package/src/charts/helpers/ValueAtFinder.ts +19 -5
  157. package/src/charts/index.scss +16 -19
  158. package/src/charts/maps.scss +0 -0
  159. package/src/charts/palette.scss +11 -31
  160. package/src/charts/palette.variables.scss +23 -0
  161. package/src/charts/variables.scss +35 -3
  162. package/src/data/StructuredSelector.ts +2 -2
  163. package/src/data/createAccessorModelProxy.ts +66 -74
  164. package/src/index.scss +5 -6
  165. package/src/maps.scss +5 -0
  166. package/src/svg/Ellipse.tsx +62 -55
  167. package/src/svg/Line.tsx +57 -42
  168. package/src/svg/Svg.scss +6 -6
  169. package/src/svg/Text.scss +19 -0
  170. package/src/svg/Text.tsx +172 -116
  171. package/src/svg/index.scss +3 -2
  172. package/src/svg/maps.scss +0 -0
  173. package/src/svg/variables.scss +0 -0
  174. package/src/ui/Container.spec.ts +59 -0
  175. package/src/ui/Controller.spec.tsx +30 -0
  176. package/src/ui/Controller.ts +5 -0
  177. package/src/ui/HoverSync.tsx +179 -147
  178. package/src/ui/Prop.ts +1 -1
  179. package/src/ui/Text.ts +12 -9
  180. package/src/ui/adapter/GroupAdapter.spec.ts +42 -0
  181. package/src/ui/adapter/GroupAdapter.ts +25 -14
  182. package/src/ui/app/History.ts +1 -1
  183. package/src/ui/index.scss +1 -1
  184. package/src/ui/layout/LabelsLeftLayout.scss +5 -7
  185. package/src/ui/layout/LabelsTopLayout.scss +4 -6
  186. package/src/ui/layout/index.scss +2 -3
  187. package/src/ui/maps.scss +0 -0
  188. package/src/ui/variables.scss +1 -2
  189. package/src/util/index.scss +4 -2
  190. package/src/util/maps.scss +1 -0
  191. package/src/util/scss/besm.scss +15 -0
  192. package/src/util/scss/calc.scss +103 -11
  193. package/src/util/scss/defaults.scss +24 -0
  194. package/src/util/scss/elements.scss +78 -0
  195. package/src/util/scss/global.scss +15 -0
  196. package/src/util/scss/include.scss +17 -9
  197. package/src/util/scss/index.scss +1 -9
  198. package/src/util/scss/maps.scss +2 -0
  199. package/src/util/scss/pad-size.scss +9 -0
  200. package/src/util/scss/padding.scss +6 -0
  201. package/src/util/scss/screen-size.scss +5 -0
  202. package/src/util/scss/variables.scss +6 -0
  203. package/src/util/variables.scss +1 -0
  204. package/src/variables.scss +5 -217
  205. package/src/widgets/Button.maps.scss +103 -0
  206. package/src/widgets/Button.scss +33 -9
  207. package/src/widgets/Button.variables.scss +8 -104
  208. package/src/widgets/CxCredit.scss +2 -0
  209. package/src/widgets/FlexBox.scss +16 -11
  210. package/src/widgets/Heading.scss +6 -0
  211. package/src/widgets/HighlightedSearchText.scss +8 -1
  212. package/src/widgets/Icon.scss +6 -0
  213. package/src/widgets/List.scss +7 -0
  214. package/src/widgets/List.tsx +6 -7
  215. package/src/widgets/ProgressBar.scss +9 -0
  216. package/src/widgets/Resizer.scss +9 -7
  217. package/src/widgets/Section.scss +53 -56
  218. package/src/widgets/animations.scss +4 -2
  219. package/src/widgets/box.scss +47 -0
  220. package/src/widgets/drag-drop/DragClone.scss +12 -4
  221. package/src/widgets/drag-drop/DragHandle.scss +12 -6
  222. package/src/widgets/drag-drop/DragSource.scss +12 -6
  223. package/src/widgets/drag-drop/DropZone.scss +9 -0
  224. package/src/widgets/drag-drop/DropZone.tsx +3 -3
  225. package/src/widgets/drag-drop/index.scss +4 -4
  226. package/src/widgets/drag-drop/maps.scss +7 -0
  227. package/src/widgets/drag-drop/variables.scss +8 -5
  228. package/src/widgets/form/Calendar.maps.scss +54 -0
  229. package/src/widgets/form/Calendar.scss +49 -11
  230. package/src/widgets/form/Calendar.tsx +755 -653
  231. package/src/widgets/form/Calendar.variables.scss +3 -46
  232. package/src/widgets/form/Checkbox.maps.scss +34 -0
  233. package/src/widgets/form/Checkbox.scss +14 -3
  234. package/src/widgets/form/Checkbox.variables.scss +4 -36
  235. package/src/widgets/form/ColorField.scss +21 -2
  236. package/src/widgets/form/ColorField.tsx +485 -431
  237. package/src/widgets/form/ColorPicker.maps.scss +21 -0
  238. package/src/widgets/form/ColorPicker.scss +26 -9
  239. package/src/widgets/form/ColorPicker.variables.scss +3 -16
  240. package/src/widgets/form/DateTimeField.scss +54 -21
  241. package/src/widgets/form/DateTimeField.tsx +697 -615
  242. package/src/widgets/form/DateTimePicker.scss +14 -4
  243. package/src/widgets/form/Field.maps.scss +122 -0
  244. package/src/widgets/form/Field.scss +54 -18
  245. package/src/widgets/form/Field.tsx +611 -504
  246. package/src/widgets/form/Field.variables.scss +46 -0
  247. package/src/widgets/form/HelpText.scss +8 -5
  248. package/src/widgets/form/Label.scss +10 -3
  249. package/src/widgets/form/LookupField.maps.scss +26 -0
  250. package/src/widgets/form/LookupField.scss +54 -24
  251. package/src/widgets/form/LookupField.tsx +25 -21
  252. package/src/widgets/form/MonthField.scss +48 -26
  253. package/src/widgets/form/MonthField.tsx +645 -567
  254. package/src/widgets/form/MonthPicker.maps.scss +50 -0
  255. package/src/widgets/form/MonthPicker.scss +44 -35
  256. package/src/widgets/form/MonthPicker.tsx +954 -724
  257. package/src/widgets/form/MonthPicker.variables.scss +24 -0
  258. package/src/widgets/form/NumberField.scss +19 -2
  259. package/src/widgets/form/NumberField.tsx +576 -466
  260. package/src/widgets/form/Radio.maps.scss +36 -0
  261. package/src/widgets/form/Radio.scss +12 -2
  262. package/src/widgets/form/Radio.variables.scss +3 -42
  263. package/src/widgets/form/Select.scss +25 -9
  264. package/src/widgets/form/Slider.scss +23 -14
  265. package/src/widgets/form/Switch.scss +18 -8
  266. package/src/widgets/form/TextArea.scss +14 -1
  267. package/src/widgets/form/TextField.scss +24 -3
  268. package/src/widgets/form/TextField.tsx +9 -21
  269. package/src/widgets/form/UploadButton.scss +14 -6
  270. package/src/widgets/form/ValidationError.scss +10 -6
  271. package/src/widgets/form/Wheel.scss +14 -4
  272. package/src/widgets/form/index.scss +22 -24
  273. package/src/widgets/form/maps.scss +81 -0
  274. package/src/widgets/form/variables.scss +111 -355
  275. package/src/widgets/grid/Grid.scss +19 -2
  276. package/src/widgets/grid/Grid.spec.ts +42 -0
  277. package/src/widgets/grid/Grid.tsx +15 -7
  278. package/src/widgets/grid/Pagination.scss +11 -2
  279. package/src/widgets/grid/Pagination.tsx +110 -102
  280. package/src/widgets/grid/TreeNode.scss +25 -8
  281. package/src/widgets/grid/TreeNode.tsx +127 -116
  282. package/src/widgets/grid/index.scss +3 -4
  283. package/src/widgets/grid/maps.scss +110 -0
  284. package/src/widgets/grid/variables.scss +48 -137
  285. package/src/widgets/icons/folder.tsx +1 -2
  286. package/src/widgets/icons/forward.tsx +23 -20
  287. package/src/widgets/icons/loading.tsx +22 -19
  288. package/src/widgets/icons/square.tsx +20 -17
  289. package/src/widgets/index.scss +16 -16
  290. package/src/widgets/index.ts +63 -58
  291. package/src/widgets/lists.scss +42 -0
  292. package/src/widgets/maps.scss +139 -0
  293. package/src/widgets/nav/Link.scss +14 -1
  294. package/src/widgets/nav/Menu.scss +13 -7
  295. package/src/widgets/nav/Menu.variables.scss +1 -12
  296. package/src/widgets/nav/MenuItem.scss +21 -6
  297. package/src/widgets/nav/Scroller.scss +11 -2
  298. package/src/widgets/nav/Tab.maps.scss +78 -0
  299. package/src/widgets/nav/Tab.scss +12 -6
  300. package/src/widgets/nav/Tab.variables.scss +7 -76
  301. package/src/widgets/nav/cover.scss +6 -4
  302. package/src/widgets/nav/index.scss +6 -6
  303. package/src/widgets/nav/maps.scss +32 -0
  304. package/src/widgets/nav/variables.scss +4 -11
  305. package/src/widgets/overlay/ContextMenu.ts +3 -0
  306. package/src/widgets/overlay/Dropdown.scss +47 -16
  307. package/src/widgets/overlay/Dropdown.tsx +851 -676
  308. package/src/widgets/overlay/MsgBox.tsx +125 -111
  309. package/src/widgets/overlay/Overlay.scss +60 -40
  310. package/src/widgets/overlay/Overlay.tsx +948 -800
  311. package/src/widgets/overlay/Toast.scss +42 -34
  312. package/src/widgets/overlay/Toast.ts +11 -1
  313. package/src/widgets/overlay/Tooltip.scss +27 -96
  314. package/src/widgets/overlay/Tooltip.tsx +376 -309
  315. package/src/widgets/overlay/Window.maps.scss +51 -0
  316. package/src/widgets/overlay/Window.scss +17 -17
  317. package/src/widgets/overlay/Window.tsx +291 -236
  318. package/src/widgets/overlay/Window.variables.scss +2 -43
  319. package/src/widgets/overlay/index.d.ts +11 -11
  320. package/src/widgets/overlay/index.scss +6 -15
  321. package/src/widgets/overlay/maps.scss +44 -0
  322. package/src/widgets/overlay/variables.scss +11 -42
  323. package/src/widgets/variables.scss +33 -117
  324. package/src/global.scss +0 -14
@@ -17,11 +17,11 @@ import { zeroTime } from "../../util/date/zeroTime";
17
17
  import DropdownIcon from "../icons/drop-down";
18
18
  import ForwardIcon from "../icons/forward";
19
19
  import {
20
- tooltipMouseLeave,
21
- tooltipMouseMove,
22
- tooltipParentDidMount,
23
- tooltipParentWillReceiveProps,
24
- tooltipParentWillUnmount,
20
+ tooltipMouseLeave,
21
+ tooltipMouseMove,
22
+ tooltipParentDidMount,
23
+ tooltipParentWillReceiveProps,
24
+ tooltipParentWillUnmount,
25
25
  } from "../overlay/tooltip-ops";
26
26
  import { Field, FieldConfig, getFieldTooltip, FieldInstance } from "./Field";
27
27
  import type { Instance } from "../../ui/Instance";
@@ -29,218 +29,255 @@ import type { RenderingContext } from "../../ui/RenderingContext";
29
29
  import { BooleanProp, DataRecord, Prop } from "../../ui/Prop";
30
30
 
31
31
  interface DayInfo {
32
- mod?: string;
33
- className?: string;
34
- style?: DataRecord | string;
35
- unselectable?: boolean;
36
- disabled?: boolean;
32
+ mod?: string;
33
+ className?: string;
34
+ style?: DataRecord | string;
35
+ unselectable?: boolean;
36
+ disabled?: boolean;
37
37
  }
38
38
 
39
39
  interface DayData {
40
- [day: string]: DayInfo;
40
+ [day: string]: DayInfo;
41
41
  }
42
42
 
43
43
  export interface CalendarConfig extends FieldConfig {
44
- /** Selected date. This should be a `Date` object or a valid date string consumable by `Date.parse` function. */
45
- value?: Prop<string | Date>;
44
+ /** Selected date. This should be a `Date` object or a valid date string consumable by `Date.parse` function. */
45
+ value?: Prop<string | Date>;
46
46
 
47
- /** View reference date. If no date is selected, this date is used to determine which month to show in the calendar. */
48
- refDate?: Prop<string | Date>;
47
+ /** View reference date. If no date is selected, this date is used to determine which month to show in the calendar. */
48
+ refDate?: Prop<string | Date>;
49
49
 
50
- /** Minimum date value. This should be a `Date` object or a valid date string consumable by `Date.parse` function. */
51
- minValue?: Prop<string | Date>;
50
+ /** Minimum date value. This should be a `Date` object or a valid date string consumable by `Date.parse` function. */
51
+ minValue?: Prop<string | Date>;
52
52
 
53
- /** Set to `true` to disallow the `minValue`. Default value is `false`. */
54
- minExclusive?: BooleanProp;
53
+ /** Set to `true` to disallow the `minValue`. Default value is `false`. */
54
+ minExclusive?: BooleanProp;
55
55
 
56
- /** Maximum date value. This should be a `Date` object or a valid date string consumable by `Date.parse` function. */
57
- maxValue?: Prop<string | Date>;
56
+ /** Maximum date value. This should be a `Date` object or a valid date string consumable by `Date.parse` function. */
57
+ maxValue?: Prop<string | Date>;
58
58
 
59
- /** Set to `true` to disallow the `maxValue`. Default value is `false`. */
60
- maxExclusive?: BooleanProp;
59
+ /** Set to `true` to disallow the `maxValue`. Default value is `false`. */
60
+ maxExclusive?: BooleanProp;
61
61
 
62
- /** Base CSS class to be applied to the calendar. Defaults to `calendar`. */
63
- baseClass?: string;
62
+ /** Base CSS class to be applied to the calendar. Defaults to `calendar`. */
63
+ baseClass?: string;
64
64
 
65
- /** Highlight today's date. Default is true. */
66
- highlightToday?: boolean;
65
+ /** Highlight today's date. Default is true. */
66
+ highlightToday?: boolean;
67
67
 
68
- /** Maximum value error text. */
69
- maxValueErrorText?: string;
68
+ /** Maximum value error text. */
69
+ maxValueErrorText?: string;
70
70
 
71
- /** Maximum exclusive value error text. */
72
- maxExclusiveErrorText?: string;
71
+ /** Maximum exclusive value error text. */
72
+ maxExclusiveErrorText?: string;
73
73
 
74
- /** Minimum value error text. */
75
- minValueErrorText?: string;
74
+ /** Minimum value error text. */
75
+ minValueErrorText?: string;
76
76
 
77
- /** Minimum exclusive value error text. */
78
- minExclusiveErrorText?: string;
77
+ /** Minimum exclusive value error text. */
78
+ minExclusiveErrorText?: string;
79
79
 
80
- /** The function that will be used to convert Date objects before writing data to the store.
81
- * Default implementation is Date.toISOString.
82
- * See also Culture.setDefaultDateEncoding.
83
- */
84
- encoding?: (date: Date) => any;
80
+ /** The function that will be used to convert Date objects before writing data to the store.
81
+ * Default implementation is Date.toISOString.
82
+ * See also Culture.setDefaultDateEncoding.
83
+ */
84
+ encoding?: (date: Date) => any;
85
85
 
86
- /** Set to true to show the button for quickly selecting today's date. */
87
- showTodayButton?: boolean;
86
+ /** Set to true to show the button for quickly selecting today's date. */
87
+ showTodayButton?: boolean;
88
88
 
89
- /** Localizable text for the todayButton. Defaults to `"Today"`. */
90
- todayButtonText?: string;
89
+ /** Localizable text for the todayButton. Defaults to `"Today"`. */
90
+ todayButtonText?: string;
91
91
 
92
- /** Defines which days of week should be displayed as disabled, i.e. `[0, 6]` will make Sunday and Saturday unselectable. */
93
- disabledDaysOfWeek?: number[];
92
+ /** Defines which days of week should be displayed as disabled, i.e. `[0, 6]` will make Sunday and Saturday unselectable. */
93
+ disabledDaysOfWeek?: number[];
94
94
 
95
- /** Set to true to show weeks starting from Monday. */
96
- startWithMonday?: boolean;
95
+ /** Set to true to show weeks starting from Monday. */
96
+ startWithMonday?: boolean;
97
97
 
98
- /** Map of days to additional day information such as style, className, mod, unselectable and disabled. */
99
- dayData?: Prop<DayData>;
98
+ /** Map of days to additional day information such as style, className, mod, unselectable and disabled. */
99
+ dayData?: Prop<DayData>;
100
100
  }
101
101
 
102
102
  export class Calendar extends Field<CalendarConfig> {
103
- declare public baseClass: string;
104
- declare public unfocusable?: boolean;
105
- declare public focusable?: boolean;
106
- declare public highlightToday?: boolean;
107
- declare public maxValueErrorText?: string;
108
- declare public maxExclusiveErrorText?: string;
109
- declare public minValueErrorText?: string;
110
- declare public minExclusiveErrorText?: string;
111
- declare public disabledDaysOfWeekErrorText?: string;
112
- declare public showTodayButton?: boolean;
113
- declare public todayButtonText?: string;
114
- declare public startWithMonday?: boolean;
115
- declare public onBeforeSelect?: string | ((e: React.MouseEvent, instance: Instance, date: Date) => boolean | void);
116
- declare public onSelect?: string | ((e: React.MouseEvent, instance: Instance, date: Date) => void);
117
- declare public onBlur?: string | ((e: React.FocusEvent, instance: Instance) => void);
118
- declare public onFocusOut?: string | ((instance: Instance) => void);
119
- declare public disabledDaysOfWeek?: number[];
120
- declare public partial?: boolean;
121
- declare public encoding?: (date: Date) => string;
122
-
123
- constructor(config?: CalendarConfig) {
124
- super(config);
125
- }
126
-
127
- declareData(...args: Record<string, unknown>[]) {
128
- super.declareData(
129
- {
130
- value: undefined,
131
- refDate: undefined,
132
- disabled: undefined,
133
- enabled: undefined,
134
- minValue: undefined,
135
- minExclusive: undefined,
136
- maxValue: undefined,
137
- maxExclusive: undefined,
138
- focusable: undefined,
139
- dayData: undefined,
140
- },
141
- ...args,
142
- );
143
- }
144
-
145
- init() {
146
- if (this.unfocusable) this.focusable = false;
147
-
148
- super.init();
149
- }
150
-
151
- prepareData(context: RenderingContext, instance: FieldInstance<Calendar>, ...args: any[]) {
152
- const { data } = instance;
153
- data.stateMods = {
154
- disabled: data.disabled,
155
- };
156
-
157
- if (data.value) {
158
- let d = parseDateInvariant(data.value);
159
- if (!isNaN(d.getTime())) {
160
- data.date = zeroTime(d);
161
- }
103
+ declare public baseClass: string;
104
+ declare public unfocusable?: boolean;
105
+ declare public focusable?: boolean;
106
+ declare public highlightToday?: boolean;
107
+ declare public maxValueErrorText?: string;
108
+ declare public maxExclusiveErrorText?: string;
109
+ declare public minValueErrorText?: string;
110
+ declare public minExclusiveErrorText?: string;
111
+ declare public disabledDaysOfWeekErrorText?: string;
112
+ declare public showTodayButton?: boolean;
113
+ declare public todayButtonText?: string;
114
+ declare public startWithMonday?: boolean;
115
+ declare public onBeforeSelect?:
116
+ | string
117
+ | ((e: React.MouseEvent, instance: Instance, date: Date) => boolean | void);
118
+ declare public onSelect?:
119
+ | string
120
+ | ((e: React.MouseEvent, instance: Instance, date: Date) => void);
121
+ declare public onBlur?:
122
+ | string
123
+ | ((e: React.FocusEvent, instance: Instance) => void);
124
+ declare public onFocusOut?: string | ((instance: Instance) => void);
125
+ declare public disabledDaysOfWeek?: number[];
126
+ declare public partial?: boolean;
127
+ declare public encoding?: (date: Date) => string;
128
+
129
+ constructor(config?: CalendarConfig) {
130
+ super(config);
131
+ }
132
+
133
+ declareData(...args: Record<string, unknown>[]) {
134
+ super.declareData(
135
+ {
136
+ value: undefined,
137
+ refDate: undefined,
138
+ disabled: undefined,
139
+ enabled: undefined,
140
+ minValue: undefined,
141
+ minExclusive: undefined,
142
+ maxValue: undefined,
143
+ maxExclusive: undefined,
144
+ focusable: undefined,
145
+ dayData: undefined,
146
+ },
147
+ ...args,
148
+ );
149
+ }
150
+
151
+ init() {
152
+ if (this.unfocusable) this.focusable = false;
153
+
154
+ super.init();
155
+ }
156
+
157
+ prepareData(
158
+ context: RenderingContext,
159
+ instance: FieldInstance<Calendar>,
160
+ ...args: any[]
161
+ ) {
162
+ const { data } = instance;
163
+ data.stateMods = {
164
+ disabled: data.disabled,
165
+ };
166
+
167
+ if (data.value) {
168
+ let d = parseDateInvariant(data.value);
169
+ if (!isNaN(d.getTime())) {
170
+ data.date = zeroTime(d);
162
171
  }
163
-
164
- if (data.refDate) data.refDate = zeroTime(parseDateInvariant(data.refDate));
165
-
166
- if (data.maxValue) data.maxValue = zeroTime(parseDateInvariant(data.maxValue));
167
-
168
- if (data.minValue) data.minValue = zeroTime(parseDateInvariant(data.minValue));
169
-
170
- super.prepareData(context, instance, ...args);
171
- }
172
-
173
- validate(context: RenderingContext, instance: FieldInstance<Calendar>) {
174
- super.validate(context, instance);
175
- let { data, widget } = instance;
176
- let calendarWidget = widget as Calendar;
177
-
178
- if (!data.error && data.date) {
179
- let d;
180
- if (data.maxValue) {
181
- d = dateDiff(data.date, data.maxValue);
182
- if (d > 0) data.error = StringTemplate.format(this.maxValueErrorText!, data.maxValue);
183
- else if (d == 0 && data.maxExclusive)
184
- data.error = StringTemplate.format(this.maxExclusiveErrorText!, data.maxValue);
185
- }
186
-
187
- if (data.minValue) {
188
- d = dateDiff(data.date, data.minValue);
189
- if (d < 0) data.error = StringTemplate.format(this.minValueErrorText!, data.minValue);
190
- else if (d == 0 && data.minExclusive)
191
- data.error = StringTemplate.format(this.minExclusiveErrorText!, data.minValue);
192
- }
193
-
194
- if (calendarWidget.disabledDaysOfWeek) {
195
- if (calendarWidget.disabledDaysOfWeek.includes(data.date.getDay()))
196
- data.error = this.disabledDaysOfWeekErrorText;
197
- }
198
-
199
- if (data.dayData) {
200
- let date = parseDateInvariant(data.value);
201
- let info = data.dayData[date.toDateString()];
202
- if (info && info.disabled) data.error = this.disabledDaysOfWeekErrorText;
203
- }
172
+ }
173
+
174
+ if (data.refDate) data.refDate = zeroTime(parseDateInvariant(data.refDate));
175
+
176
+ if (data.maxValue)
177
+ data.maxValue = zeroTime(parseDateInvariant(data.maxValue));
178
+
179
+ if (data.minValue)
180
+ data.minValue = zeroTime(parseDateInvariant(data.minValue));
181
+
182
+ super.prepareData(context, instance, ...args);
183
+ }
184
+
185
+ validate(context: RenderingContext, instance: FieldInstance<Calendar>) {
186
+ super.validate(context, instance);
187
+ let { data, widget } = instance;
188
+ let calendarWidget = widget as Calendar;
189
+
190
+ if (!data.error && data.date) {
191
+ let d;
192
+ if (data.maxValue) {
193
+ d = dateDiff(data.date, data.maxValue);
194
+ if (d > 0)
195
+ data.error = StringTemplate.format(
196
+ this.maxValueErrorText!,
197
+ data.maxValue,
198
+ );
199
+ else if (d == 0 && data.maxExclusive)
200
+ data.error = StringTemplate.format(
201
+ this.maxExclusiveErrorText!,
202
+ data.maxValue,
203
+ );
204
204
  }
205
- }
206
-
207
- renderInput(context: RenderingContext, instance: any, key: string): React.ReactElement {
208
- return (
209
- <CalendarCmp
210
- key={key}
211
- instance={instance}
212
- handleSelect={(e: React.MouseEvent, date: Date) => this.handleSelect(e, instance, date)}
213
- />
214
- );
215
- }
216
-
217
- handleSelect(e: React.MouseEvent, instance: any, date: Date): void {
218
- let { store, data, widget } = instance;
219
- let calendarWidget = widget as Calendar;
220
-
221
- e.stopPropagation();
222
205
 
223
- if (data.disabled) return;
224
-
225
- if (!validationCheck(date, data, calendarWidget.disabledDaysOfWeek)) return;
206
+ if (data.minValue) {
207
+ d = dateDiff(data.date, data.minValue);
208
+ if (d < 0)
209
+ data.error = StringTemplate.format(
210
+ this.minValueErrorText!,
211
+ data.minValue,
212
+ );
213
+ else if (d == 0 && data.minExclusive)
214
+ data.error = StringTemplate.format(
215
+ this.minExclusiveErrorText!,
216
+ data.minValue,
217
+ );
218
+ }
226
219
 
227
- if (this.onBeforeSelect && instance.invoke("onBeforeSelect", e, instance, date) === false) return;
220
+ if (calendarWidget.disabledDaysOfWeek) {
221
+ if (calendarWidget.disabledDaysOfWeek.includes(data.date.getDay()))
222
+ data.error = this.disabledDaysOfWeekErrorText;
223
+ }
228
224
 
229
- if (calendarWidget.partial) {
230
- let mixed = parseDateInvariant(data.value);
231
- if (data.value && !isNaN(mixed.getTime())) {
232
- mixed.setFullYear(date.getFullYear());
233
- mixed.setMonth(date.getMonth());
234
- mixed.setDate(date.getDate());
235
- date = mixed;
236
- }
225
+ if (data.dayData) {
226
+ let date = parseDateInvariant(data.value);
227
+ let info = data.dayData[date.toDateString()];
228
+ if (info && info.disabled)
229
+ data.error = this.disabledDaysOfWeekErrorText;
230
+ }
231
+ }
232
+ }
233
+
234
+ renderInput(
235
+ context: RenderingContext,
236
+ instance: any,
237
+ key: string,
238
+ ): React.ReactElement {
239
+ return (
240
+ <CalendarCmp
241
+ key={key}
242
+ instance={instance}
243
+ handleSelect={(e: React.MouseEvent, date: Date) =>
244
+ this.handleSelect(e, instance, date)
245
+ }
246
+ />
247
+ );
248
+ }
249
+
250
+ handleSelect(e: React.MouseEvent, instance: any, date: Date): void {
251
+ let { store, data, widget } = instance;
252
+ let calendarWidget = widget as Calendar;
253
+
254
+ e.stopPropagation();
255
+
256
+ if (data.disabled) return;
257
+
258
+ if (!validationCheck(date, data, calendarWidget.disabledDaysOfWeek)) return;
259
+
260
+ if (
261
+ this.onBeforeSelect &&
262
+ instance.invoke("onBeforeSelect", e, instance, date) === false
263
+ )
264
+ return;
265
+
266
+ if (calendarWidget.partial) {
267
+ let mixed = parseDateInvariant(data.value);
268
+ if (data.value && !isNaN(mixed.getTime())) {
269
+ mixed.setFullYear(date.getFullYear());
270
+ mixed.setMonth(date.getMonth());
271
+ mixed.setDate(date.getDate());
272
+ date = mixed;
237
273
  }
274
+ }
238
275
 
239
- let encode = calendarWidget.encoding || Culture.getDefaultDateEncoding()!;
240
- instance.set("value", encode(date));
276
+ let encode = calendarWidget.encoding || Culture.getDefaultDateEncoding()!;
277
+ instance.set("value", encode(date));
241
278
 
242
- if (this.onSelect) instance.invoke("onSelect", e, instance, date);
243
- }
279
+ if (this.onSelect) instance.invoke("onSelect", e, instance, date);
280
+ }
244
281
  }
245
282
 
246
283
  Calendar.prototype.baseClass = "calendar";
@@ -249,7 +286,8 @@ Calendar.prototype.maxValueErrorText = "Select a date not after {0:d}.";
249
286
  Calendar.prototype.maxExclusiveErrorText = "Select a date before {0:d}.";
250
287
  Calendar.prototype.minValueErrorText = "Select a date not before {0:d}.";
251
288
  Calendar.prototype.minExclusiveErrorText = "Select a date after {0:d}.";
252
- Calendar.prototype.disabledDaysOfWeekErrorText = "Selected day of week is not allowed.";
289
+ Calendar.prototype.disabledDaysOfWeekErrorText =
290
+ "Selected day of week is not allowed.";
253
291
  Calendar.prototype.suppressErrorsUntilVisited = false;
254
292
  Calendar.prototype.showTodayButton = false;
255
293
  Calendar.prototype.todayButtonText = "Today";
@@ -259,502 +297,566 @@ Calendar.prototype.focusable = true;
259
297
  Localization.registerPrototype("cx/widgets/Calendar", Calendar);
260
298
 
261
299
  interface CalendarData {
262
- maxValue?: Date;
263
- maxExclusive?: boolean;
264
- minValue?: Date;
265
- minExclusive?: boolean;
266
- dayData?: Record<string, DayInfo>;
300
+ maxValue?: Date;
301
+ maxExclusive?: boolean;
302
+ minValue?: Date;
303
+ minExclusive?: boolean;
304
+ dayData?: Record<string, DayInfo>;
267
305
  }
268
306
 
269
- const validationCheck = (date: Date, data: CalendarData, disabledDaysOfWeek?: number[]): boolean => {
270
- if (data.maxValue && !upperBoundCheck(date, data.maxValue, data.maxExclusive)) return false;
307
+ const validationCheck = (
308
+ date: Date,
309
+ data: CalendarData,
310
+ disabledDaysOfWeek?: number[],
311
+ ): boolean => {
312
+ if (data.maxValue && !upperBoundCheck(date, data.maxValue, data.maxExclusive))
313
+ return false;
271
314
 
272
- if (data.minValue && !lowerBoundCheck(date, data.minValue, data.minExclusive)) return false;
315
+ if (data.minValue && !lowerBoundCheck(date, data.minValue, data.minExclusive))
316
+ return false;
273
317
 
274
- if (disabledDaysOfWeek && disabledDaysOfWeek.includes(date.getDay())) return false;
318
+ if (disabledDaysOfWeek && disabledDaysOfWeek.includes(date.getDay()))
319
+ return false;
275
320
 
276
- if (data.dayData) {
277
- let day = data.dayData[date.toDateString()];
278
- if (day && (day.disabled || day.unselectable)) return false;
279
- }
321
+ if (data.dayData) {
322
+ let day = data.dayData[date.toDateString()];
323
+ if (day && (day.disabled || day.unselectable)) return false;
324
+ }
280
325
 
281
- return true;
326
+ return true;
282
327
  };
283
328
 
284
329
  interface CalendarCmpProps {
285
- instance: FieldInstance<Calendar>;
286
- handleSelect: (e: React.MouseEvent, date: Date) => void;
330
+ instance: FieldInstance<Calendar>;
331
+ handleSelect: (e: React.MouseEvent, date: Date) => void;
287
332
  }
288
333
 
289
334
  interface CalendarState {
290
- hover: boolean;
291
- focus: boolean;
292
- cursor: Date;
293
- activeView: string;
294
- refDate: Date;
295
- startDate: Date;
296
- endDate: Date;
297
- yearPickerHeight?: number;
335
+ hover: boolean;
336
+ focus: boolean;
337
+ cursor: Date;
338
+ activeView: string;
339
+ refDate: Date;
340
+ startDate: Date;
341
+ endDate: Date;
342
+ yearPickerHeight?: number;
298
343
  }
299
344
 
300
- export class CalendarCmp extends VDOM.Component<CalendarCmpProps, CalendarState> {
301
- el: HTMLElement | null = null;
302
-
303
- constructor(props: CalendarCmpProps) {
304
- super(props);
305
- let { data } = props.instance;
306
-
307
- let refDate = data.refDate ? data.refDate : data.date || zeroTime(new Date());
308
-
309
- this.state = {
310
- hover: false,
311
- focus: false,
312
- cursor: zeroTime(data.date || refDate),
313
- activeView: "calendar",
314
- ...this.getPage(refDate),
315
- };
316
-
317
- this.handleMouseMove = this.handleMouseMove.bind(this);
318
- this.handleMouseDown = this.handleMouseDown.bind(this);
319
- }
320
-
321
- getPage(refDate: Date): { refDate: Date; startDate: Date; endDate: Date } {
322
- refDate = monthStart(refDate); //make a copy
323
-
324
- let calendarWidget = this.props.instance.widget as Calendar;
325
- let startWithMonday = calendarWidget.startWithMonday;
326
-
327
- let startDay = startWithMonday ? 1 : 0;
328
- let startDate = new Date(refDate);
329
- while (startDate.getDay() != startDay) startDate.setDate(startDate.getDate() - 1);
330
-
331
- let endDate = new Date(refDate);
332
- endDate.setMonth(refDate.getMonth() + 1);
333
- endDate.setDate(endDate.getDate() - 1);
334
-
335
- let endDay = startWithMonday ? 0 : 6;
336
- while (endDate.getDay() != endDay) endDate.setDate(endDate.getDate() + 1);
337
-
338
- return {
339
- refDate,
340
- startDate,
341
- endDate,
342
- };
343
- }
344
-
345
- moveCursor(e: React.SyntheticEvent | React.KeyboardEvent, date: Date, options: { movePage?: boolean } = {}): void {
346
- e.preventDefault();
347
- e.stopPropagation();
348
-
349
- date = zeroTime(date);
350
- if (date.getTime() == this.state.cursor.getTime()) return;
351
-
352
- let refDate = this.state.refDate;
353
-
354
- if (options.movePage || date < this.state.startDate || date > this.state.endDate) refDate = date;
355
-
356
- this.setState({
357
- ...this.getPage(refDate),
358
- cursor: date,
345
+ export class CalendarCmp extends VDOM.Component<
346
+ CalendarCmpProps,
347
+ CalendarState
348
+ > {
349
+ el: HTMLElement | null = null;
350
+
351
+ constructor(props: CalendarCmpProps) {
352
+ super(props);
353
+ let { data } = props.instance;
354
+
355
+ let refDate = data.refDate
356
+ ? data.refDate
357
+ : data.date || zeroTime(new Date());
358
+
359
+ this.state = {
360
+ hover: false,
361
+ focus: false,
362
+ cursor: zeroTime(data.date || refDate),
363
+ activeView: "calendar",
364
+ ...this.getPage(refDate),
365
+ };
366
+
367
+ this.handleMouseMove = this.handleMouseMove.bind(this);
368
+ this.handleMouseDown = this.handleMouseDown.bind(this);
369
+ }
370
+
371
+ getPage(refDate: Date): { refDate: Date; startDate: Date; endDate: Date } {
372
+ refDate = monthStart(refDate); //make a copy
373
+
374
+ let calendarWidget = this.props.instance.widget as Calendar;
375
+ let startWithMonday = calendarWidget.startWithMonday;
376
+
377
+ let startDay = startWithMonday ? 1 : 0;
378
+ let startDate = new Date(refDate);
379
+ while (startDate.getDay() != startDay)
380
+ startDate.setDate(startDate.getDate() - 1);
381
+
382
+ let endDate = new Date(refDate);
383
+ endDate.setMonth(refDate.getMonth() + 1);
384
+ endDate.setDate(endDate.getDate() - 1);
385
+
386
+ let endDay = startWithMonday ? 0 : 6;
387
+ while (endDate.getDay() != endDay) endDate.setDate(endDate.getDate() + 1);
388
+
389
+ return {
390
+ refDate,
391
+ startDate,
392
+ endDate,
393
+ };
394
+ }
395
+
396
+ moveCursor(
397
+ e: React.SyntheticEvent | React.KeyboardEvent,
398
+ date: Date,
399
+ options: { movePage?: boolean } = {},
400
+ ): void {
401
+ e.preventDefault();
402
+ e.stopPropagation();
403
+
404
+ date = zeroTime(date);
405
+ if (date.getTime() == this.state.cursor.getTime()) return;
406
+
407
+ let refDate = this.state.refDate;
408
+
409
+ if (
410
+ options.movePage ||
411
+ date < this.state.startDate ||
412
+ date > this.state.endDate
413
+ )
414
+ refDate = date;
415
+
416
+ this.setState({
417
+ ...this.getPage(refDate),
418
+ cursor: date,
419
+ });
420
+ }
421
+
422
+ move(e: React.MouseEvent, period: string, delta: number): void {
423
+ e.preventDefault();
424
+ e.stopPropagation();
425
+
426
+ let refDate = new Date(this.state.refDate);
427
+
428
+ switch (period) {
429
+ case "y":
430
+ refDate.setFullYear(refDate.getFullYear() + delta);
431
+ break;
432
+
433
+ case "m":
434
+ refDate.setMonth(refDate.getMonth() + delta);
435
+ break;
436
+ }
437
+
438
+ let page = this.getPage(refDate);
439
+ let cursor = this.state.cursor;
440
+ if (cursor < page.startDate) cursor = page.startDate;
441
+ else if (cursor > page.endDate) cursor = page.endDate;
442
+
443
+ this.setState({ ...page, cursor });
444
+ }
445
+
446
+ handleKeyPress(e: React.KeyboardEvent): void {
447
+ let cursor = new Date(this.state.cursor);
448
+
449
+ switch (e.keyCode) {
450
+ case KeyCode.enter:
451
+ this.props.handleSelect(
452
+ e as unknown as React.MouseEvent,
453
+ this.state.cursor,
454
+ );
455
+ break;
456
+
457
+ case KeyCode.left:
458
+ cursor.setDate(cursor.getDate() - 1);
459
+ this.moveCursor(e, cursor);
460
+ break;
461
+
462
+ case KeyCode.right:
463
+ cursor.setDate(cursor.getDate() + 1);
464
+ this.moveCursor(e, cursor);
465
+ break;
466
+
467
+ case KeyCode.up:
468
+ cursor.setDate(cursor.getDate() - 7);
469
+ this.moveCursor(e, cursor);
470
+ break;
471
+
472
+ case KeyCode.down:
473
+ cursor.setDate(cursor.getDate() + 7);
474
+ this.moveCursor(e, cursor);
475
+ break;
476
+
477
+ case KeyCode.pageUp:
478
+ cursor.setMonth(cursor.getMonth() - 1);
479
+ this.moveCursor(e, cursor, { movePage: true });
480
+ break;
481
+
482
+ case KeyCode.pageDown:
483
+ cursor.setMonth(cursor.getMonth() + 1);
484
+ this.moveCursor(e, cursor, { movePage: true });
485
+ break;
486
+
487
+ case KeyCode.home:
488
+ cursor.setDate(1);
489
+ this.moveCursor(e, cursor, { movePage: true });
490
+ break;
491
+
492
+ case KeyCode.end:
493
+ cursor.setMonth(cursor.getMonth() + 1);
494
+ cursor.setDate(0);
495
+ this.moveCursor(e, cursor, { movePage: true });
496
+ break;
497
+
498
+ default:
499
+ let { instance } = this.props;
500
+ let calendarWidget = instance.widget as Calendar;
501
+ if (calendarWidget.onKeyDown) instance.invoke("onKeyDown", e, instance);
502
+ break;
503
+ }
504
+ }
505
+
506
+ handleWheel(e: WheelEvent): void {
507
+ e.preventDefault();
508
+ e.stopPropagation();
509
+
510
+ let cursor = new Date(this.state.cursor);
511
+
512
+ if (e.deltaY < 0) {
513
+ cursor.setMonth(cursor.getMonth() - 1);
514
+ this.moveCursor(e as unknown as React.SyntheticEvent, cursor, {
515
+ movePage: true,
359
516
  });
360
- }
361
-
362
- move(e: React.MouseEvent, period: string, delta: number): void {
363
- e.preventDefault();
364
- e.stopPropagation();
365
-
366
- let refDate = new Date(this.state.refDate);
367
-
368
- switch (period) {
369
- case "y":
370
- refDate.setFullYear(refDate.getFullYear() + delta);
371
- break;
372
-
373
- case "m":
374
- refDate.setMonth(refDate.getMonth() + delta);
375
- break;
376
- }
377
-
378
- let page = this.getPage(refDate);
379
- let cursor = this.state.cursor;
380
- if (cursor < page.startDate) cursor = page.startDate;
381
- else if (cursor > page.endDate) cursor = page.endDate;
382
-
383
- this.setState({ ...page, cursor });
384
- }
385
-
386
- handleKeyPress(e: React.KeyboardEvent): void {
387
- let cursor = new Date(this.state.cursor);
388
-
389
- switch (e.keyCode) {
390
- case KeyCode.enter:
391
- this.props.handleSelect(e as unknown as React.MouseEvent, this.state.cursor);
392
- break;
393
-
394
- case KeyCode.left:
395
- cursor.setDate(cursor.getDate() - 1);
396
- this.moveCursor(e, cursor);
397
- break;
398
-
399
- case KeyCode.right:
400
- cursor.setDate(cursor.getDate() + 1);
401
- this.moveCursor(e, cursor);
402
- break;
403
-
404
- case KeyCode.up:
405
- cursor.setDate(cursor.getDate() - 7);
406
- this.moveCursor(e, cursor);
407
- break;
408
-
409
- case KeyCode.down:
410
- cursor.setDate(cursor.getDate() + 7);
411
- this.moveCursor(e, cursor);
412
- break;
413
-
414
- case KeyCode.pageUp:
415
- cursor.setMonth(cursor.getMonth() - 1);
416
- this.moveCursor(e, cursor, { movePage: true });
417
- break;
418
-
419
- case KeyCode.pageDown:
420
- cursor.setMonth(cursor.getMonth() + 1);
421
- this.moveCursor(e, cursor, { movePage: true });
422
- break;
423
-
424
- case KeyCode.home:
425
- cursor.setDate(1);
426
- this.moveCursor(e, cursor, { movePage: true });
427
- break;
428
-
429
- case KeyCode.end:
430
- cursor.setMonth(cursor.getMonth() + 1);
431
- cursor.setDate(0);
432
- this.moveCursor(e, cursor, { movePage: true });
433
- break;
434
-
435
- default:
436
- let { instance } = this.props;
437
- let calendarWidget = instance.widget as Calendar;
438
- if (calendarWidget.onKeyDown) instance.invoke("onKeyDown", e, instance);
439
- break;
440
- }
441
- }
442
-
443
- handleWheel(e: WheelEvent): void {
444
- e.preventDefault();
445
- e.stopPropagation();
446
-
447
- let cursor = new Date(this.state.cursor);
448
-
449
- if (e.deltaY < 0) {
450
- cursor.setMonth(cursor.getMonth() - 1);
451
- this.moveCursor(e as unknown as React.SyntheticEvent, cursor, { movePage: true });
452
- } else if (e.deltaY > 0) {
453
- cursor.setMonth(cursor.getMonth() + 1);
454
- this.moveCursor(e as unknown as React.SyntheticEvent, cursor, { movePage: true });
455
- }
456
- }
457
-
458
- handleBlur(e: React.FocusEvent): void {
459
- FocusManager.nudge();
460
- let { instance } = this.props;
461
- let calendarWidget = instance.widget as Calendar;
462
- if (calendarWidget.onBlur) instance.invoke("onBlur", e, instance);
463
- this.setState({
464
- focus: false,
465
- });
466
- }
467
-
468
- handleFocus(e: React.FocusEvent): void {
469
- oneFocusOut(this, this.el!, this.handleFocusOut.bind(this));
470
- this.setState({
471
- focus: true,
472
- });
473
- }
474
-
475
- handleFocusOut(): void {
476
- let { instance } = this.props;
477
- let calendarWidget = instance.widget as Calendar;
478
- if (calendarWidget.onFocusOut) instance.invoke("onFocusOut", null, instance);
479
- }
480
-
481
- handleMouseLeave(e: React.MouseEvent): void {
482
- tooltipMouseLeave(e, ...getFieldTooltip(this.props.instance));
483
- this.setState({
484
- hover: false,
517
+ } else if (e.deltaY > 0) {
518
+ cursor.setMonth(cursor.getMonth() + 1);
519
+ this.moveCursor(e as unknown as React.SyntheticEvent, cursor, {
520
+ movePage: true,
485
521
  });
486
- }
487
-
488
- handleMouseEnter(e: React.MouseEvent): void {
522
+ }
523
+ }
524
+
525
+ handleBlur(e: React.FocusEvent): void {
526
+ FocusManager.nudge();
527
+ let { instance } = this.props;
528
+ let calendarWidget = instance.widget as Calendar;
529
+ if (calendarWidget.onBlur) instance.invoke("onBlur", e, instance);
530
+ this.setState({
531
+ focus: false,
532
+ });
533
+ }
534
+
535
+ handleFocus(e: React.FocusEvent): void {
536
+ oneFocusOut(this, this.el!, this.handleFocusOut.bind(this));
537
+ this.setState({
538
+ focus: true,
539
+ });
540
+ }
541
+
542
+ handleFocusOut(): void {
543
+ let { instance } = this.props;
544
+ let calendarWidget = instance.widget as Calendar;
545
+ if (calendarWidget.onFocusOut)
546
+ instance.invoke("onFocusOut", null, instance);
547
+ }
548
+
549
+ handleMouseLeave(e: React.MouseEvent): void {
550
+ tooltipMouseLeave(e, ...getFieldTooltip(this.props.instance));
551
+ this.setState({
552
+ hover: false,
553
+ });
554
+ }
555
+
556
+ handleMouseEnter(e: React.MouseEvent): void {
557
+ this.setState({
558
+ hover: true,
559
+ });
560
+ }
561
+
562
+ handleMouseMove(e: React.MouseEvent): void {
563
+ this.moveCursor(e, readDate((e.target as HTMLElement).dataset));
564
+ }
565
+
566
+ handleMouseDown(e: React.MouseEvent): void {
567
+ this.props.handleSelect(e, readDate((e.target as HTMLElement).dataset));
568
+ }
569
+
570
+ componentDidMount(): void {
571
+ //calendar doesn't bring up keyboard so it's ok to focus it even on mobile
572
+ let calendarWidget = this.props.instance.widget as Calendar;
573
+ if (calendarWidget.autoFocus && this.el) this.el.focus();
574
+
575
+ if (this.el) {
576
+ tooltipParentDidMount(this.el, ...getFieldTooltip(this.props.instance));
577
+ this.el.addEventListener("wheel", (e) => this.handleWheel(e));
578
+ }
579
+ }
580
+
581
+ UNSAFE_componentWillReceiveProps(props: CalendarCmpProps): void {
582
+ let { data } = props.instance;
583
+ if (data.date)
489
584
  this.setState({
490
- hover: true,
585
+ ...this.getPage(data.date),
491
586
  });
492
- }
493
-
494
- handleMouseMove(e: React.MouseEvent): void {
495
- this.moveCursor(e, readDate((e.target as HTMLElement).dataset));
496
- }
497
-
498
- handleMouseDown(e: React.MouseEvent): void {
499
- this.props.handleSelect(e, readDate((e.target as HTMLElement).dataset));
500
- }
501
-
502
- componentDidMount(): void {
503
- //calendar doesn't bring up keyboard so it's ok to focus it even on mobile
504
- let calendarWidget = this.props.instance.widget as Calendar;
505
- if (calendarWidget.autoFocus && this.el) this.el.focus();
506
587
 
507
- if (this.el) {
508
- tooltipParentDidMount(this.el, ...getFieldTooltip(this.props.instance));
509
- this.el.addEventListener("wheel", (e) => this.handleWheel(e));
510
- }
511
- }
512
-
513
- UNSAFE_componentWillReceiveProps(props: CalendarCmpProps): void {
514
- let { data } = props.instance;
515
- if (data.date)
516
- this.setState({
517
- ...this.getPage(data.date),
518
- });
588
+ if (this.el) {
589
+ tooltipParentWillReceiveProps(
590
+ this.el,
591
+ ...getFieldTooltip(props.instance),
592
+ );
593
+ }
594
+ }
519
595
 
520
- if (this.el) {
521
- tooltipParentWillReceiveProps(this.el, ...getFieldTooltip(props.instance));
522
- }
523
- }
524
-
525
- componentWillUnmount(): void {
526
- offFocusOut(this);
527
- tooltipParentWillUnmount(this.props.instance);
528
- }
529
-
530
- showYearDropdown(): void {
531
- if (this.el && this.el.firstChild) {
532
- this.setState({
533
- activeView: "year-picker",
534
- yearPickerHeight: (this.el.firstChild as HTMLElement).offsetHeight,
535
- });
536
- }
537
- }
596
+ componentWillUnmount(): void {
597
+ offFocusOut(this);
598
+ tooltipParentWillUnmount(this.props.instance);
599
+ }
538
600
 
539
- handleYearSelect(e: React.MouseEvent, year: number): void {
540
- e.preventDefault();
541
- e.stopPropagation();
542
- let refDate = new Date(this.state.refDate);
543
- refDate.setFullYear(year);
601
+ showYearDropdown(): void {
602
+ if (this.el && this.el.firstChild) {
544
603
  this.setState({
545
- ...this.getPage(refDate),
546
- activeView: "calendar",
604
+ activeView: "year-picker",
605
+ yearPickerHeight: (this.el.firstChild as HTMLElement).offsetHeight,
547
606
  });
548
- }
549
-
550
- renderYearPicker(): React.ReactElement {
551
- let { data, widget } = this.props.instance;
552
- let calendarWidget = widget as Calendar;
553
- let minYear: number | undefined = data.minValue?.getFullYear();
554
- let maxYear: number | undefined = data.maxValue?.getFullYear();
555
- let { CSS } = widget;
556
-
557
- let years: number[] = [];
558
- let currentYear = new Date().getFullYear();
559
- let midYear = currentYear - (currentYear % 5);
560
- let refYear = new Date(this.state.refDate).getFullYear();
561
- for (let i = midYear - 100; i <= midYear + 100; i++) {
562
- years.push(i);
563
- }
564
-
565
- let rows: number[][] = [];
566
- for (let i = 0; i < years.length; i += 5) {
567
- rows.push(years.slice(i, i + 5));
607
+ }
608
+ }
609
+
610
+ handleYearSelect(e: React.MouseEvent, year: number): void {
611
+ e.preventDefault();
612
+ e.stopPropagation();
613
+ let refDate = new Date(this.state.refDate);
614
+ refDate.setFullYear(year);
615
+ this.setState({
616
+ ...this.getPage(refDate),
617
+ activeView: "calendar",
618
+ });
619
+ }
620
+
621
+ renderYearPicker(): React.ReactElement {
622
+ let { data, widget } = this.props.instance;
623
+ let calendarWidget = widget as Calendar;
624
+ let minYear: number | undefined = data.minValue?.getFullYear();
625
+ let maxYear: number | undefined = data.maxValue?.getFullYear();
626
+ let { CSS } = widget;
627
+
628
+ let years: number[] = [];
629
+ let currentYear = new Date().getFullYear();
630
+ let midYear = currentYear - (currentYear % 5);
631
+ let refYear = new Date(this.state.refDate).getFullYear();
632
+ for (let i = midYear - 100; i <= midYear + 100; i++) {
633
+ years.push(i);
634
+ }
635
+
636
+ let rows: number[][] = [];
637
+ for (let i = 0; i < years.length; i += 5) {
638
+ rows.push(years.slice(i, i + 5));
639
+ }
640
+ return (
641
+ <div
642
+ className={CSS.element(calendarWidget.baseClass, "year-picker")}
643
+ style={{
644
+ height: this.state.yearPickerHeight,
645
+ }}
646
+ ref={(el) => {
647
+ if (el) {
648
+ el.addEventListener("wheel", (e) => {
649
+ e.stopPropagation();
650
+ });
651
+
652
+ let activeYear = el.querySelector("." + CSS.state("selected"));
653
+ if (activeYear)
654
+ activeYear.scrollIntoView({
655
+ block: "center",
656
+ behavior: "instant",
657
+ });
658
+ }
659
+ }}
660
+ >
661
+ <table>
662
+ <tbody>
663
+ {rows.map((row: number[], rowIndex: number) => (
664
+ <tr key={rowIndex}>
665
+ {row.map((year: number) => (
666
+ <td
667
+ key={year}
668
+ className={CSS.element(
669
+ calendarWidget.baseClass,
670
+ "year-option",
671
+ {
672
+ unselectable:
673
+ (minYear && year < minYear) ||
674
+ (maxYear && year > maxYear),
675
+ selected: year === refYear,
676
+ active: year === currentYear,
677
+ },
678
+ )}
679
+ onClick={(e) => this.handleYearSelect(e, year)}
680
+ >
681
+ {year}
682
+ </td>
683
+ ))}
684
+ </tr>
685
+ ))}
686
+ </tbody>
687
+ </table>
688
+ </div>
689
+ );
690
+ }
691
+
692
+ render(): React.ReactElement {
693
+ let { data, widget } = this.props.instance;
694
+ let calendarWidget = widget as Calendar;
695
+ let { CSS, baseClass, disabledDaysOfWeek, startWithMonday } =
696
+ calendarWidget;
697
+
698
+ let { refDate, startDate, endDate } = this.getPage(this.state.refDate);
699
+
700
+ let month = refDate.getMonth();
701
+ let year = refDate.getFullYear();
702
+ let weeks: React.ReactNode[] = [];
703
+ let date = startDate;
704
+
705
+ let empty: Record<string, any> = {};
706
+
707
+ let today = zeroTime(new Date());
708
+ while (date >= startDate && date <= endDate) {
709
+ let days: React.ReactNode[] = [];
710
+ for (let i = 0; i < 7; i++) {
711
+ let dayInfo =
712
+ (data.dayData && data.dayData[date.toDateString()]) || empty;
713
+ let unselectable = !validationCheck(date, data, disabledDaysOfWeek);
714
+ let classNames = CSS.expand(
715
+ CSS.element(baseClass, "day", {
716
+ outside: month != date.getMonth(),
717
+ unselectable: unselectable,
718
+ selected: data.date && sameDate(data.date, date),
719
+ cursor:
720
+ (this.state.hover || this.state.focus) &&
721
+ this.state.cursor &&
722
+ sameDate(this.state.cursor, date),
723
+ today: calendarWidget.highlightToday && sameDate(date, today),
724
+ }),
725
+ dayInfo.className,
726
+ CSS.mod(dayInfo.mod),
727
+ );
728
+ let dateInst = new Date(date);
729
+ days.push(
730
+ <td
731
+ key={i}
732
+ className={classNames}
733
+ style={CSS.parseStyle(dayInfo.style)}
734
+ data-year={dateInst.getFullYear()}
735
+ data-month={dateInst.getMonth() + 1}
736
+ data-date={dateInst.getDate()}
737
+ onMouseMove={unselectable ? undefined : this.handleMouseMove}
738
+ onMouseDown={unselectable ? undefined : this.handleMouseDown}
739
+ >
740
+ {date.getDate()}
741
+ </td>,
742
+ );
743
+ date.setDate(date.getDate() + 1);
568
744
  }
569
- return (
570
- <div
571
- className={CSS.element(calendarWidget.baseClass, "year-picker")}
572
- style={{
573
- height: this.state.yearPickerHeight,
574
- }}
575
- ref={(el) => {
576
- if (el) {
577
- el.addEventListener("wheel", (e) => {
578
- e.stopPropagation();
579
- });
580
-
581
- let activeYear = el.querySelector("." + CSS.state("selected"));
582
- if (activeYear) activeYear.scrollIntoView({ block: "center", behavior: "instant" });
583
- }
584
- }}
585
- >
586
- <table>
587
- <tbody>
588
- {rows.map((row: number[], rowIndex: number) => (
589
- <tr key={rowIndex}>
590
- {row.map((year: number) => (
591
- <td
592
- key={year}
593
- className={CSS.element(calendarWidget.baseClass, "year-option", {
594
- unselectable: (minYear && year < minYear) || (maxYear && year > maxYear),
595
- selected: year === refYear,
596
- active: year === currentYear,
597
- })}
598
- onClick={(e) => this.handleYearSelect(e, year)}
599
- >
600
- {year}
601
- </td>
602
- ))}
603
- </tr>
604
- ))}
605
- </tbody>
606
- </table>
607
- </div>
745
+ weeks.push(
746
+ <tr key={weeks.length} className={CSS.element(baseClass, "week")}>
747
+ <td />
748
+ {days}
749
+ <td />
750
+ </tr>,
608
751
  );
609
- }
610
-
611
- render(): React.ReactElement {
612
- let { data, widget } = this.props.instance;
613
- let calendarWidget = widget as Calendar;
614
- let { CSS, baseClass, disabledDaysOfWeek, startWithMonday } = calendarWidget;
615
-
616
- let { refDate, startDate, endDate } = this.getPage(this.state.refDate);
617
-
618
- let month = refDate.getMonth();
619
- let year = refDate.getFullYear();
620
- let weeks: React.ReactNode[] = [];
621
- let date = startDate;
622
-
623
- let empty: Record<string, any> = {};
624
-
625
- let today = zeroTime(new Date());
626
- while (date >= startDate && date <= endDate) {
627
- let days: React.ReactNode[] = [];
628
- for (let i = 0; i < 7; i++) {
629
- let dayInfo = (data.dayData && data.dayData[date.toDateString()]) || empty;
630
- let unselectable = !validationCheck(date, data, disabledDaysOfWeek);
631
- let classNames = CSS.expand(
632
- CSS.element(baseClass, "day", {
633
- outside: month != date.getMonth(),
634
- unselectable: unselectable,
635
- selected: data.date && sameDate(data.date, date),
636
- cursor:
637
- (this.state.hover || this.state.focus) && this.state.cursor && sameDate(this.state.cursor, date),
638
- today: calendarWidget.highlightToday && sameDate(date, today),
639
- }),
640
- dayInfo.className,
641
- CSS.mod(dayInfo.mod),
642
- );
643
- let dateInst = new Date(date);
644
- days.push(
645
- <td
646
- key={i}
647
- className={classNames}
648
- style={CSS.parseStyle(dayInfo.style)}
649
- data-year={dateInst.getFullYear()}
650
- data-month={dateInst.getMonth() + 1}
651
- data-date={dateInst.getDate()}
652
- onMouseMove={unselectable ? undefined : this.handleMouseMove}
653
- onMouseDown={unselectable ? undefined : this.handleMouseDown}
654
- >
655
- {date.getDate()}
656
- </td>,
657
- );
658
- date.setDate(date.getDate() + 1);
659
- }
660
- weeks.push(
661
- <tr key={weeks.length} className={CSS.element(baseClass, "week")}>
662
- <td />
663
- {days}
664
- <td />
665
- </tr>,
666
- );
667
- }
668
-
669
- let culture = Culture.getDateTimeCulture();
670
- let monthNames = culture.getMonthNames("long");
671
- let dayNames = culture.getWeekdayNames("short").map((x: string) => x.substr(0, 2));
672
- if (startWithMonday) dayNames = [...dayNames.slice(1), dayNames[0]];
673
-
674
- return (
675
- <div
676
- className={data.classNames}
677
- tabIndex={data.disabled || !data.focusable ? null : data.tabIndex || 0}
678
- onKeyDown={(e) => this.handleKeyPress(e)}
679
- onMouseDown={(e) => {
680
- // prevent losing focus from the input field
681
- if (!data.focusable) {
682
- e.preventDefault();
683
- }
684
- e.stopPropagation();
685
- }}
686
- ref={(el) => {
687
- this.el = el;
688
- }}
689
- onMouseMove={(e) => tooltipMouseMove(e, ...getFieldTooltip(this.props.instance))}
690
- onMouseLeave={(e) => this.handleMouseLeave(e)}
691
- onMouseEnter={(e) => this.handleMouseEnter(e)}
692
- // onWheel={(e) => this.handleWheel(e)}
693
- onFocus={(e) => this.handleFocus(e)}
694
- onBlur={(e) => this.handleBlur(e)}
695
- >
696
- {this.state.activeView == "calendar" && (
697
- <table>
698
- <thead>
699
- <tr key="h" className={CSS.element(baseClass, "header")}>
700
- <td />
701
- <td onClick={(e) => this.move(e, "y", -1)}>
702
- <ForwardIcon className={CSS.element(baseClass, "icon-prev-year")} />
703
- </td>
704
- <td onClick={(e) => this.move(e, "m", -1)}>
705
- <DropdownIcon className={CSS.element(baseClass, "icon-prev-month")} />
706
- </td>
707
- <th className={CSS.element(baseClass, "display")} colSpan={3}>
708
- {monthNames[month]}
709
- <br />
710
- <span
711
- onClick={() => this.showYearDropdown()}
712
- className={CSS.element(baseClass, "year-name")}
713
- >
714
- {year}
715
- </span>
716
- </th>
717
- <td onClick={(e) => this.move(e, "m", +1)}>
718
- <DropdownIcon className={CSS.element(baseClass, "icon-next-month")} />
719
- </td>
720
- <td onClick={(e) => this.move(e, "y", +1)}>
721
- <ForwardIcon className={CSS.element(baseClass, "icon-next-year")} />
722
- </td>
723
- <td />
724
- </tr>
725
- <tr key="d" className={CSS.element(baseClass, "day-names")}>
726
- <td />
727
- {dayNames.map((name: string, i: number) => (
728
- <th key={i}>{name}</th>
729
- ))}
730
- <td />
731
- </tr>
732
- </thead>
733
- <tbody>{weeks}</tbody>
734
- </table>
735
- )}
736
- {this.state.activeView == "calendar" && calendarWidget.showTodayButton && (
737
- <div className={CSS.element(baseClass, "toolbar")}>
738
- <button
739
- className={CSS.expand(CSS.element(baseClass, "today-button"), CSS.block("button", "hollow"))}
740
- data-year={today.getFullYear()}
741
- data-month={today.getMonth() + 1}
742
- data-date={today.getDate()}
743
- onClick={(e) => {
744
- this.handleMouseDown(e);
745
- }}
752
+ }
753
+
754
+ let culture = Culture.getDateTimeCulture();
755
+ let monthNames = culture.getMonthNames("long");
756
+ let dayNames = culture
757
+ .getWeekdayNames("short")
758
+ .map((x: string) => x.substr(0, 2));
759
+ if (startWithMonday) dayNames = [...dayNames.slice(1), dayNames[0]];
760
+
761
+ return (
762
+ <div
763
+ className={data.classNames}
764
+ tabIndex={data.disabled || !data.focusable ? null : data.tabIndex || 0}
765
+ onKeyDown={(e) => this.handleKeyPress(e)}
766
+ onMouseDown={(e) => {
767
+ // prevent losing focus from the input field
768
+ if (!data.focusable) {
769
+ e.preventDefault();
770
+ }
771
+ e.stopPropagation();
772
+ }}
773
+ ref={(el) => {
774
+ this.el = el;
775
+ }}
776
+ onMouseMove={(e) =>
777
+ tooltipMouseMove(e, ...getFieldTooltip(this.props.instance))
778
+ }
779
+ onMouseLeave={(e) => this.handleMouseLeave(e)}
780
+ onMouseEnter={(e) => this.handleMouseEnter(e)}
781
+ // onWheel={(e) => this.handleWheel(e)}
782
+ onFocus={(e) => this.handleFocus(e)}
783
+ onBlur={(e) => this.handleBlur(e)}
784
+ >
785
+ {this.state.activeView == "calendar" && (
786
+ <table>
787
+ <thead>
788
+ <tr key="h" className={CSS.element(baseClass, "header")}>
789
+ <td />
790
+ <td onClick={(e) => this.move(e, "y", -1)}>
791
+ <ForwardIcon
792
+ className={CSS.element(baseClass, "icon-prev-year")}
793
+ />
794
+ </td>
795
+ <td onClick={(e) => this.move(e, "m", -1)}>
796
+ <DropdownIcon
797
+ className={CSS.element(baseClass, "icon-prev-month")}
798
+ />
799
+ </td>
800
+ <th className={CSS.element(baseClass, "display")} colSpan={3}>
801
+ {monthNames[month]}
802
+ <br />
803
+ <span
804
+ onClick={() => this.showYearDropdown()}
805
+ className={CSS.element(baseClass, "year-name")}
746
806
  >
747
- {calendarWidget.todayButtonText}
748
- </button>
749
- </div>
750
- )}
751
-
752
- {this.state.activeView == "year-picker" && this.renderYearPicker()}
753
- </div>
754
- );
755
- }
807
+ {year}
808
+ </span>
809
+ </th>
810
+ <td onClick={(e) => this.move(e, "m", +1)}>
811
+ <DropdownIcon
812
+ className={CSS.element(baseClass, "icon-next-month")}
813
+ />
814
+ </td>
815
+ <td onClick={(e) => this.move(e, "y", +1)}>
816
+ <ForwardIcon
817
+ className={CSS.element(baseClass, "icon-next-year")}
818
+ />
819
+ </td>
820
+ <td />
821
+ </tr>
822
+ <tr key="d" className={CSS.element(baseClass, "day-names")}>
823
+ <td />
824
+ {dayNames.map((name: string, i: number) => (
825
+ <th key={i}>{name}</th>
826
+ ))}
827
+ <td />
828
+ </tr>
829
+ </thead>
830
+ <tbody>{weeks}</tbody>
831
+ </table>
832
+ )}
833
+ {this.state.activeView == "calendar" &&
834
+ calendarWidget.showTodayButton && (
835
+ <div className={CSS.element(baseClass, "toolbar")}>
836
+ <button
837
+ className={CSS.expand(
838
+ CSS.element(baseClass, "today-button"),
839
+ CSS.block("button", "hollow"),
840
+ )}
841
+ data-year={today.getFullYear()}
842
+ data-month={today.getMonth() + 1}
843
+ data-date={today.getDate()}
844
+ onClick={(e) => {
845
+ this.handleMouseDown(e);
846
+ }}
847
+ >
848
+ {calendarWidget.todayButtonText}
849
+ </button>
850
+ </div>
851
+ )}
852
+
853
+ {this.state.activeView == "year-picker" && this.renderYearPicker()}
854
+ </div>
855
+ );
856
+ }
756
857
  }
757
858
 
758
- const readDate = (ds: DOMStringMap): Date => new Date(Number(ds.year), Number(ds.month) - 1, Number(ds.date));
859
+ const readDate = (ds: DOMStringMap): Date =>
860
+ new Date(Number(ds.year), Number(ds.month) - 1, Number(ds.date));
759
861
 
760
862
  Widget.alias("calendar", Calendar);