goblin-gadgets 3.2.2 → 3.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 (361) hide show
  1. package/.editorconfig +9 -9
  2. package/.eslintrc.js +28 -28
  3. package/.zou-flow +2 -2
  4. package/builders/builders.js +5 -5
  5. package/builders/gadget.js +85 -85
  6. package/calendar-boards-gadget.js +64 -64
  7. package/demo-gadget.js +17 -17
  8. package/glyphs-dialog.js +13 -13
  9. package/login-dialog.js +13 -13
  10. package/package.json +46 -46
  11. package/pivot-gadget.js +18 -18
  12. package/stack-navigation.js +13 -13
  13. package/table-gadget.js +102 -102
  14. package/test/code-parser.spec.js +61 -61
  15. package/tree-gadget.js +70 -70
  16. package/types/types.js +455 -455
  17. package/widgets/accordion/styles.js +16 -16
  18. package/widgets/accordion/widget.js +90 -90
  19. package/widgets/analog-clock/props.js +102 -102
  20. package/widgets/analog-clock/scenarios.js +43 -43
  21. package/widgets/analog-clock/styles.js +754 -754
  22. package/widgets/analog-clock/widget.js +404 -404
  23. package/widgets/animated-container/animations.js +566 -566
  24. package/widgets/animated-container/styles.js +36 -36
  25. package/widgets/animated-container/widget.js +24 -24
  26. package/widgets/badge/styles.js +107 -107
  27. package/widgets/badge/widget.js +33 -33
  28. package/widgets/button/props.js +377 -377
  29. package/widgets/button/scenarios.js +54 -54
  30. package/widgets/button/styles.js +1082 -1082
  31. package/widgets/button/widget.js +426 -426
  32. package/widgets/button-combo/styles.js +73 -73
  33. package/widgets/button-combo/widget.js +297 -297
  34. package/widgets/calendar/props.js +207 -207
  35. package/widgets/calendar/scenarios.js +50 -50
  36. package/widgets/calendar/styles.js +198 -198
  37. package/widgets/calendar/widget.js +895 -895
  38. package/widgets/calendar-boards/styles.js +29 -29
  39. package/widgets/calendar-boards/widget.js +215 -215
  40. package/widgets/calendar-button/styles.js +273 -273
  41. package/widgets/calendar-button/widget.js +94 -94
  42. package/widgets/calendar-list/styles.js +35 -35
  43. package/widgets/calendar-list/widget.js +223 -223
  44. package/widgets/calendar-recurrence/widget.js +183 -183
  45. package/widgets/carousel/props.js +104 -104
  46. package/widgets/carousel/scenarios.js +163 -163
  47. package/widgets/carousel/styles.js +133 -133
  48. package/widgets/carousel/widget.js +491 -491
  49. package/widgets/carousel-bullet/styles.js +29 -29
  50. package/widgets/carousel-bullet/widget.js +25 -25
  51. package/widgets/carousel-button/styles.js +71 -71
  52. package/widgets/carousel-button/widget.js +33 -33
  53. package/widgets/carousel-item/styles.js +21 -21
  54. package/widgets/carousel-item/widget.js +24 -24
  55. package/widgets/chat-balloon/props.js +65 -65
  56. package/widgets/chat-balloon/scenarios.js +47 -47
  57. package/widgets/chat-balloon/styles.js +193 -193
  58. package/widgets/chat-balloon/widget.js +62 -62
  59. package/widgets/chat-dialog/styles.js +15 -15
  60. package/widgets/chat-dialog/widget.js +62 -62
  61. package/widgets/check-list/styles.js +66 -66
  62. package/widgets/check-list/widget.js +168 -168
  63. package/widgets/checkbox/widget.js +15 -15
  64. package/widgets/checkbox-nc/props.js +191 -191
  65. package/widgets/checkbox-nc/scenarios.js +41 -41
  66. package/widgets/checkbox-nc/styles.js +122 -122
  67. package/widgets/checkbox-nc/widget.js +116 -116
  68. package/widgets/clock-combo/styles.js +174 -174
  69. package/widgets/clock-combo/widget.js +390 -390
  70. package/widgets/color-picker/props.js +145 -145
  71. package/widgets/color-picker/scenarios.js +34 -34
  72. package/widgets/color-picker/styles.js +209 -209
  73. package/widgets/color-picker/widget.js +735 -735
  74. package/widgets/colored-container/props.js +34 -34
  75. package/widgets/colored-container/scenarios.js +54 -54
  76. package/widgets/colored-container/styles.js +100 -100
  77. package/widgets/colored-container/widget.js +27 -27
  78. package/widgets/combo/styles.js +69 -69
  79. package/widgets/combo/widget.js +224 -224
  80. package/widgets/combo-container/styles.js +66 -66
  81. package/widgets/combo-container/widget.js +188 -188
  82. package/widgets/command-button/widget.js +39 -39
  83. package/widgets/container/props.js +295 -295
  84. package/widgets/container/scenarios.js +47 -47
  85. package/widgets/container/styles.js +1439 -1439
  86. package/widgets/container/widget.js +279 -279
  87. package/widgets/demo/widget.js +24 -24
  88. package/widgets/dialog/styles.js +29 -29
  89. package/widgets/dialog/widget.js +26 -26
  90. package/widgets/dialog-modal/props.js +126 -126
  91. package/widgets/dialog-modal/styles.js +234 -234
  92. package/widgets/dialog-modal/widget.js +273 -273
  93. package/widgets/dialog-resizable/props.js +1 -1
  94. package/widgets/dialog-resizable/scenarios.js +18 -18
  95. package/widgets/dialog-resizable/widget.js +367 -367
  96. package/widgets/dialog-resizable-nc/props.js +150 -150
  97. package/widgets/dialog-resizable-nc/scenarios.js +18 -18
  98. package/widgets/dialog-resizable-nc/styles.js +259 -259
  99. package/widgets/dialog-resizable-nc/widget.js +197 -197
  100. package/widgets/directory-input/widget.js +18 -18
  101. package/widgets/directory-input-nc/widget.js +20 -20
  102. package/widgets/document-container/getPath.js +43 -43
  103. package/widgets/document-container/props.js +79 -79
  104. package/widgets/document-container/scenarios.js +39 -39
  105. package/widgets/document-container/styles.js +69 -69
  106. package/widgets/document-container/widget.js +53 -53
  107. package/widgets/drag-cab/styles.js +56 -56
  108. package/widgets/drag-cab/widget.js +285 -285
  109. package/widgets/drag-carrier/styles.js +21 -21
  110. package/widgets/drag-carrier/widget.js +780 -780
  111. package/widgets/dynamic-toolbar/styles.js +110 -110
  112. package/widgets/dynamic-toolbar/widget.js +128 -128
  113. package/widgets/field/readonly/label.js +39 -39
  114. package/widgets/field/widget.js +1743 -1743
  115. package/widgets/file-input/widget.js +18 -18
  116. package/widgets/file-input-nc/styles.js +38 -38
  117. package/widgets/file-input-nc/widget.js +88 -88
  118. package/widgets/flat-combo/styles.js +21 -21
  119. package/widgets/flat-combo/widget.js +61 -61
  120. package/widgets/flat-list/styles.js +30 -30
  121. package/widgets/flat-list/widget.js +219 -219
  122. package/widgets/flying-balloon/styles.js +52 -52
  123. package/widgets/flying-balloon/widget.js +43 -43
  124. package/widgets/fragment/widget.js +26 -26
  125. package/widgets/full-screen/props.js +27 -27
  126. package/widgets/full-screen/styles.js +32 -32
  127. package/widgets/full-screen/widget.js +40 -40
  128. package/widgets/gauge/props.js +71 -71
  129. package/widgets/gauge/scenarios.js +83 -83
  130. package/widgets/gauge/styles.js +183 -183
  131. package/widgets/gauge/widget.js +36 -36
  132. package/widgets/glyph-detail/service.js +9 -9
  133. package/widgets/glyph-detail/widget.js +109 -109
  134. package/widgets/glyphs-dialog/service.js +94 -94
  135. package/widgets/glyphs-dialog/styles.js +37 -37
  136. package/widgets/glyphs-dialog/widget.js +236 -236
  137. package/widgets/goblin-editor/widget.js +146 -146
  138. package/widgets/guild-entry/props.js +53 -53
  139. package/widgets/guild-entry/scenarios.js +26 -26
  140. package/widgets/guild-entry/styles.js +98 -98
  141. package/widgets/guild-entry/widget.js +126 -126
  142. package/widgets/guild-user-logo/guild-helpers.js +77 -77
  143. package/widgets/guild-user-logo/props.js +48 -48
  144. package/widgets/guild-user-logo/scenarios.js +64 -64
  145. package/widgets/guild-user-logo/styles.js +114 -114
  146. package/widgets/guild-user-logo/widget.js +81 -81
  147. package/widgets/guild-user-profile/props.js +73 -73
  148. package/widgets/guild-user-profile/scenarios.js +54 -54
  149. package/widgets/guild-user-profile/styles.js +162 -162
  150. package/widgets/guild-user-profile/widget.js +202 -202
  151. package/widgets/helpers/combo-helpers.js +218 -218
  152. package/widgets/helpers/geom-helpers.js +80 -80
  153. package/widgets/helpers/rect-helpers.js +10 -10
  154. package/widgets/helpers/shortcut-helpers.js +56 -56
  155. package/widgets/helpers/spacing-helpers.js +26 -26
  156. package/widgets/helpers/svg-helpers.js +151 -151
  157. package/widgets/helpers/table-helpers.js +68 -68
  158. package/widgets/hinter/styles.js +79 -79
  159. package/widgets/hinter/widget.js +205 -205
  160. package/widgets/hinter-column/widget.js +49 -49
  161. package/widgets/hinter-field/reducer.js +18 -18
  162. package/widgets/hinter-field/widget.js +176 -176
  163. package/widgets/hinter-field-nc/props.js +114 -114
  164. package/widgets/hinter-field-nc/scenarios.js +47 -47
  165. package/widgets/hinter-field-nc/widget.js +191 -191
  166. package/widgets/input-wrapper/widget.js +157 -157
  167. package/widgets/key-trap.js +96 -96
  168. package/widgets/label/props.js +1 -1
  169. package/widgets/label/scenarios.js +1 -1
  170. package/widgets/label/widget.js +7 -7
  171. package/widgets/label-nc/props.js +308 -308
  172. package/widgets/label-nc/scenarios.js +29 -29
  173. package/widgets/label-nc/styles.js +1218 -1218
  174. package/widgets/label-nc/widget.js +314 -314
  175. package/widgets/label-row/props.js +1 -1
  176. package/widgets/label-row/scenarios.js +1 -1
  177. package/widgets/label-row/widget.js +7 -7
  178. package/widgets/label-row-nc/props.js +94 -94
  179. package/widgets/label-row-nc/scenarios.js +46 -46
  180. package/widgets/label-row-nc/widget.js +81 -81
  181. package/widgets/label-text-field/styles.js +55 -55
  182. package/widgets/label-text-field/widget.js +178 -178
  183. package/widgets/launcher/props.js +177 -177
  184. package/widgets/launcher/scenarios.js +55 -55
  185. package/widgets/launcher/styles.js +46 -46
  186. package/widgets/launcher/widget.js +79 -79
  187. package/widgets/launcher-blob/props.js +25 -25
  188. package/widgets/launcher-blob/scenarios.js +24 -24
  189. package/widgets/launcher-blob/styles.js +62 -62
  190. package/widgets/launcher-blob/widget.js +50 -50
  191. package/widgets/list/widget.js +211 -211
  192. package/widgets/login-dialog/service.js +117 -117
  193. package/widgets/login-dialog/widget.js +117 -117
  194. package/widgets/map/reaflet.js +208 -208
  195. package/widgets/map/widget.js +67 -67
  196. package/widgets/markdown/styles.js +85 -85
  197. package/widgets/markdown/widget.js +31 -31
  198. package/widgets/notification/styles.js +97 -97
  199. package/widgets/notification/widget.js +207 -207
  200. package/widgets/pivot/custom.css +320 -320
  201. package/widgets/pivot/widget.js +42 -42
  202. package/widgets/radio-list/styles.js +48 -48
  203. package/widgets/radio-list/widget.js +111 -111
  204. package/widgets/resizable-container/styles.js +108 -108
  205. package/widgets/resizable-container/widget.js +225 -225
  206. package/widgets/retro-action-button/helpers.js +106 -106
  207. package/widgets/retro-action-button/styles.js +285 -285
  208. package/widgets/retro-action-button/widget.js +364 -364
  209. package/widgets/retro-badge-button/styles.js +87 -87
  210. package/widgets/retro-badge-button/widget.js +251 -251
  211. package/widgets/retro-gear/helpers.js +156 -156
  212. package/widgets/retro-gear/styles.js +130 -130
  213. package/widgets/retro-gear/widget.js +51 -51
  214. package/widgets/retro-illuminated-button/styles.js +274 -274
  215. package/widgets/retro-illuminated-button/widget.js +147 -147
  216. package/widgets/retro-panel/helpers.js +57 -57
  217. package/widgets/retro-panel/styles.js +293 -293
  218. package/widgets/retro-panel/widget.js +239 -239
  219. package/widgets/retro-screw/styles.js +80 -80
  220. package/widgets/retro-screw/widget.js +25 -25
  221. package/widgets/rocket/props.js +124 -124
  222. package/widgets/rocket/scenarios.js +71 -71
  223. package/widgets/rocket/styles.js +306 -306
  224. package/widgets/rocket/widget.js +225 -225
  225. package/widgets/samples-monitor/helpers.js +147 -147
  226. package/widgets/samples-monitor/styles.js +529 -529
  227. package/widgets/samples-monitor/widget.js +516 -516
  228. package/widgets/scrollable-container/styles.js +58 -58
  229. package/widgets/scrollable-container/widget.js +132 -132
  230. package/widgets/scrollable-linkable-container/reducer.js +18 -18
  231. package/widgets/scrollable-linkable-container/styles.js +42 -42
  232. package/widgets/scrollable-linkable-container/widget.js +78 -78
  233. package/widgets/select/styles.js +68 -68
  234. package/widgets/select/widget.js +119 -119
  235. package/widgets/separator/props.js +46 -46
  236. package/widgets/separator/styles.js +116 -116
  237. package/widgets/separator/widget.js +27 -27
  238. package/widgets/slider/props.js +136 -136
  239. package/widgets/slider/scenarios.js +74 -74
  240. package/widgets/slider/styles.js +246 -246
  241. package/widgets/slider/widget.js +404 -404
  242. package/widgets/slider-circle/props.js +72 -72
  243. package/widgets/slider-circle/scenarios.js +16 -16
  244. package/widgets/slider-circle/styles.js +78 -78
  245. package/widgets/slider-circle/widget.js +154 -154
  246. package/widgets/slider-xy/props.js +87 -87
  247. package/widgets/slider-xy/scenarios.js +19 -19
  248. package/widgets/slider-xy/styles.js +102 -102
  249. package/widgets/slider-xy/widget.js +234 -234
  250. package/widgets/smiley/props.js +51 -51
  251. package/widgets/smiley/scenarios.js +58 -58
  252. package/widgets/smiley/styles.js +489 -489
  253. package/widgets/smiley/widget.js +72 -72
  254. package/widgets/spinner/props.js +31 -31
  255. package/widgets/spinner/scenarios.js +31 -31
  256. package/widgets/spinner/styles.js +49 -49
  257. package/widgets/spinner/widget.js +23 -23
  258. package/widgets/splitter/props.js +71 -71
  259. package/widgets/splitter/scenarios.js +182 -182
  260. package/widgets/splitter/styles.js +41 -41
  261. package/widgets/splitter/widget.js +455 -455
  262. package/widgets/stack-navigation/service.js +324 -324
  263. package/widgets/stack-navigation/widget.js +296 -296
  264. package/widgets/state-browser/styles.js +19 -19
  265. package/widgets/state-browser/widget.js +135 -135
  266. package/widgets/state-browser-dialog/styles.js +100 -100
  267. package/widgets/state-browser-dialog/widget.js +253 -253
  268. package/widgets/state-monitor/styles.js +50 -50
  269. package/widgets/state-monitor/widget.js +324 -324
  270. package/widgets/switch-on-off/props.js +30 -30
  271. package/widgets/switch-on-off/scenarios.js +34 -34
  272. package/widgets/switch-on-off/styles.js +63 -63
  273. package/widgets/switch-on-off/widget.js +41 -41
  274. package/widgets/table/helpers.js +160 -160
  275. package/widgets/table/props.js +658 -658
  276. package/widgets/table/reducer.js +196 -196
  277. package/widgets/table/scenarios.js +54 -54
  278. package/widgets/table/widget.js +253 -253
  279. package/widgets/table-cell/props.js +145 -145
  280. package/widgets/table-cell/styles.js +160 -160
  281. package/widgets/table-cell/widget.js +139 -139
  282. package/widgets/table-header-drag-manager/styles.js +184 -184
  283. package/widgets/table-header-drag-manager/widget.js +392 -392
  284. package/widgets/table-nc/styles.js +100 -100
  285. package/widgets/table-nc/widget.js +409 -409
  286. package/widgets/table-row/props.js +73 -73
  287. package/widgets/table-row/styles.js +82 -82
  288. package/widgets/table-row/widget.js +207 -207
  289. package/widgets/text-field/widget.js +18 -18
  290. package/widgets/text-field-combo/widget.js +21 -21
  291. package/widgets/text-field-combo-nc/props.js +300 -300
  292. package/widgets/text-field-combo-nc/scenarios.js +72 -72
  293. package/widgets/text-field-combo-nc/widget.js +339 -339
  294. package/widgets/text-field-date-interval/styles.js +37 -37
  295. package/widgets/text-field-date-interval/widget.js +162 -162
  296. package/widgets/text-field-nc/props.js +40 -40
  297. package/widgets/text-field-nc/scenarios.js +67 -67
  298. package/widgets/text-field-nc/widget.js +14 -14
  299. package/widgets/text-field-time-interval/styles.js +37 -37
  300. package/widgets/text-field-time-interval/widget.js +160 -160
  301. package/widgets/text-field-typed/widget.js +51 -51
  302. package/widgets/text-field-typed-nc/props.js +81 -81
  303. package/widgets/text-field-typed-nc/scenarios.js +105 -105
  304. package/widgets/text-field-typed-nc/styles.js +20 -20
  305. package/widgets/text-field-typed-nc/widget.js +749 -750
  306. package/widgets/text-input-info-nc/props.js +62 -62
  307. package/widgets/text-input-info-nc/widget.js +55 -55
  308. package/widgets/text-input-nc/props.js +143 -143
  309. package/widgets/text-input-nc/scenarios.js +44 -44
  310. package/widgets/text-input-nc/styles.js +242 -242
  311. package/widgets/text-input-nc/widget.js +234 -234
  312. package/widgets/ticket/getPath.js +128 -128
  313. package/widgets/ticket/props.js +181 -181
  314. package/widgets/ticket/scenarios.js +39 -39
  315. package/widgets/ticket/styles.js +332 -332
  316. package/widgets/ticket/ticket-helpers.js +33 -33
  317. package/widgets/ticket/widget.js +348 -348
  318. package/widgets/ticket-hover/styles.js +207 -207
  319. package/widgets/ticket-hover/widget.js +53 -53
  320. package/widgets/time-gauge/widget.js +64 -64
  321. package/widgets/tips/styles.js +48 -48
  322. package/widgets/tips/widget.js +171 -171
  323. package/widgets/translatable-text-field/styles.js +202 -202
  324. package/widgets/translatable-text-field/text-field.js +132 -132
  325. package/widgets/translatable-text-field/widget.js +660 -660
  326. package/widgets/tree/props.js +246 -246
  327. package/widgets/tree/scenarios.js +14 -14
  328. package/widgets/tree/styles.js +142 -142
  329. package/widgets/tree/widget.js +383 -383
  330. package/widgets/tree-cell/styles.js +140 -140
  331. package/widgets/tree-cell/widget.js +100 -100
  332. package/widgets/tree-row/styles.js +77 -77
  333. package/widgets/tree-row/widget.js +135 -135
  334. package/widgets/triangle/props.js +48 -48
  335. package/widgets/triangle/scenarios.js +33 -33
  336. package/widgets/triangle/styles.js +92 -92
  337. package/widgets/triangle/widget.js +36 -36
  338. package/widgets/well-done/widget.js +170 -170
  339. package/widgets/widget-doc/reducer.js +68 -68
  340. package/widgets/widget-doc/styles.js +15 -15
  341. package/widgets/widget-doc/widget-list.js +25 -25
  342. package/widgets/widget-doc/widget.js +89 -89
  343. package/widgets/widget-doc-menu/styles.js +12 -12
  344. package/widgets/widget-doc-menu/widget.js +79 -79
  345. package/widgets/widget-doc-preview/parse-code.js +20 -20
  346. package/widgets/widget-doc-preview/styles.js +77 -77
  347. package/widgets/widget-doc-preview/widget.js +481 -481
  348. package/widgets/widget-doc-preview-container/styles.js +60 -60
  349. package/widgets/widget-doc-preview-container/widget.js +129 -129
  350. package/widgets/widget-doc-properties/styles.js +41 -41
  351. package/widgets/widget-doc-properties/widget.js +307 -307
  352. package/widgets/widget-doc-property/styles.js +75 -75
  353. package/widgets/widget-doc-property/widget.js +108 -108
  354. package/widgets/widget-doc-property-control/styles.js +14 -14
  355. package/widgets/widget-doc-property-control/widget.js +343 -343
  356. package/widgets/wizard/service.js +2132 -2132
  357. package/widgets/wizard/styles.js +21 -21
  358. package/widgets/wizard/widget.js +927 -927
  359. package/widgets/work-dialog/styles.js +31 -31
  360. package/widgets/work-dialog/widget.js +162 -162
  361. package/wizard.js +13 -13
@@ -1,895 +1,895 @@
1
- import T from 't';
2
- import React from 'react';
3
- import props from './props';
4
- import scenarios from './scenarios';
5
- import {registerWidget} from 'goblin-gadgets/widgets/widget-doc/widget-list';
6
- import Widget from 'goblin-laboratory/widgets/widget';
7
- import KeyTrap from 'goblin-gadgets/widgets/key-trap.js';
8
-
9
- import Label from 'goblin-gadgets/widgets/label/widget';
10
- import Button from 'goblin-gadgets/widgets/button/widget';
11
- import CalendarButton from 'goblin-gadgets/widgets/calendar-button/widget';
12
- import Separator from 'goblin-gadgets/widgets/separator/widget';
13
- import ComboContainer from 'goblin-gadgets/widgets/combo-container/widget';
14
- import FlatList from 'goblin-gadgets/widgets/flat-list/widget';
15
- import Tips from 'goblin-gadgets/widgets/tips/widget';
16
-
17
- import {
18
- date as DateConverters,
19
- month as MonthConverters,
20
- dow as DowConverters,
21
- } from 'xcraft-core-converters';
22
- import * as styles from './styles';
23
-
24
- /******************************************************************************/
25
-
26
- class Calendar extends Widget {
27
- constructor() {
28
- super(...arguments);
29
- this.styles = styles;
30
-
31
- this.state = {
32
- showComboMonths: false,
33
- showComboYears: false,
34
- visibleDate: null,
35
- };
36
-
37
- this.setRefMonths = this.setRefMonths.bind(this);
38
- this.setRefYears = this.setRefYears.bind(this);
39
- this.onPrevMonth = this.onPrevMonth.bind(this);
40
- this.onNextMonth = this.onNextMonth.bind(this);
41
- this.onOpenComboMonths = this.onOpenComboMonths.bind(this);
42
- this.onOpenComboYears = this.onOpenComboYears.bind(this);
43
- this.onCloseComboMonths = this.onCloseComboMonths.bind(this);
44
- this.onCloseComboYears = this.onCloseComboYears.bind(this);
45
- this.onComboMonthsClicked = this.onComboMonthsClicked.bind(this);
46
- this.onComboYearsClicked = this.onComboYearsClicked.bind(this);
47
- this.onVisibleDateMonth = this.onVisibleDateMonth.bind(this);
48
- this.onVisibleDateAddMonths = this.onVisibleDateAddMonths.bind(this);
49
- this.onVisibleDatePrevYear = this.onVisibleDatePrevYear.bind(this);
50
- this.onVisibleDateNextYear = this.onVisibleDateNextYear.bind(this);
51
- this.onDateClicked = this.onDateClicked.bind(this);
52
- this.onEscKey = this.onEscKey.bind(this);
53
- this.handleWheel = this.handleWheel.bind(this);
54
- }
55
-
56
- //#region get/set
57
- get showComboMonths() {
58
- return this.state.showComboMonths;
59
- }
60
-
61
- set showComboMonths(value) {
62
- this.setState({
63
- showComboMonths: value,
64
- });
65
- }
66
-
67
- get showComboYears() {
68
- return this.state.showComboYears;
69
- }
70
-
71
- set showComboYears(value) {
72
- this.setState({
73
- showComboYears: value,
74
- });
75
- }
76
-
77
- get visibleDate() {
78
- return this.state.visibleDate || this.props.visibleDate;
79
- }
80
-
81
- set visibleDate(value) {
82
- this.setState({
83
- visibleDate: value,
84
- });
85
- }
86
- //#endregion
87
-
88
- static get wiring() {
89
- return {
90
- id: 'id',
91
- msg: 'msg',
92
- };
93
- }
94
-
95
- /******************************************************************************/
96
-
97
- UNSAFE_componentWillMount() {
98
- if (this.props.onEscKey) {
99
- KeyTrap.bind('Escape', this.onEscKey);
100
- }
101
- }
102
-
103
- componentWillUnmount() {
104
- super.componentWillUnmount();
105
- if (this.props.onEscKey) {
106
- KeyTrap.unbind('Escape', this.onEscKey);
107
- }
108
- }
109
-
110
- /******************************************************************************/
111
-
112
- setRefMonths(node) {
113
- this.nodeMonths = node;
114
- }
115
-
116
- setRefYears(node) {
117
- this.nodeYears = node;
118
- }
119
-
120
- onComboMonthsClicked(item) {
121
- this.onCloseComboMonths();
122
- this.changeDate(item.id);
123
- //? this.dateClicked(item.id);
124
- }
125
-
126
- onComboYearsClicked(item) {
127
- this.onCloseComboYears();
128
- this.changeDate(item.id);
129
- //? this.dateClicked(item.id);
130
- }
131
-
132
- get comboMonthsList() {
133
- const list = [];
134
- const year = DateConverters.getYear(this.visibleDate);
135
- const day = DateConverters.getDay(this.visibleDate);
136
- const isLast =
137
- this.visibleDate === DateConverters.moveAtEndingOfMonth(this.visibleDate);
138
- for (let month = 1; month <= 12; month++) {
139
- const date = DateConverters.getDate(year, month, isLast ? 31 : day, true);
140
- list.push({
141
- id: date,
142
- text: DateConverters.getDisplayed(date, 'M'),
143
- isLast,
144
- });
145
- }
146
- return list;
147
- }
148
-
149
- get comboYearsList() {
150
- const list = [];
151
- const nowRank = DateConverters.getYear(this.visibleDate);
152
- const month = DateConverters.getMonth(this.visibleDate);
153
- const day = DateConverters.getDay(this.visibleDate);
154
- const startCount = Math.max(
155
- this.props.startDate
156
- ? DateConverters.getYear(this.props.startDate) - nowRank
157
- : -999,
158
- -10
159
- );
160
- const endCount = Math.min(
161
- this.props.endDate
162
- ? DateConverters.getYear(this.props.endDate) - nowRank
163
- : 999,
164
- 10
165
- );
166
- for (let i = startCount; i <= endCount; i++) {
167
- const date = DateConverters.getDate(nowRank + i, month, day, true);
168
- list.push({
169
- id: date,
170
- text: DateConverters.getDisplayed(date, 'y'),
171
- });
172
- }
173
- return list;
174
- }
175
-
176
- getDateData(date) {
177
- if (!this.props.dates || this.props.dates.length === 0) {
178
- return null;
179
- } else if (typeof this.props.dates[0] === 'string') {
180
- return this.props.dates.indexOf(date) === -1 ? null : {type: 'base'};
181
- } else if (Array.isArray(this.props.dates)) {
182
- for (const d of this.props.dates) {
183
- if (d.date === date) {
184
- return d;
185
- }
186
- }
187
- return null;
188
- } else {
189
- return this.props.dates[date];
190
- }
191
- }
192
-
193
- getBadgeValue(date) {
194
- if (!this.props.badges || this.props.badges.length === 0) {
195
- return 0;
196
- } else {
197
- for (const badge of this.props.badges) {
198
- if (badge.date === date) {
199
- return badge.value;
200
- }
201
- }
202
- return 0;
203
- }
204
- }
205
-
206
- getBadgeColor(date) {
207
- if (!this.props.badges || this.props.badges.length === 0) {
208
- return null;
209
- } else {
210
- for (const badge of this.props.badges) {
211
- if (badge.date === date) {
212
- return badge.color;
213
- }
214
- }
215
- return null;
216
- }
217
- }
218
-
219
- get startVisibleDate() {
220
- const month = DateConverters.getMonth(this.visibleDate);
221
- const year = DateConverters.getYear(this.visibleDate);
222
- return DateConverters.getDate(year, month, 1);
223
- }
224
-
225
- get endVisibleDate() {
226
- return DateConverters.addDays(
227
- DateConverters.addMonths(this.startVisibleDate, this.monthCount),
228
- -1
229
- );
230
- }
231
-
232
- get monthCount() {
233
- const monthCount = this.props.monthCount;
234
- return monthCount ? Math.min(parseInt(monthCount), 12) : 1;
235
- }
236
-
237
- getDOW3Letters(dow) {
238
- return DowConverters.getDisplayed(dow, 'short');
239
- }
240
-
241
- changeDate(date) {
242
- this.visibleDate = date;
243
-
244
- const x = this.props.visibleDateChanged;
245
- if (x) {
246
- x(date);
247
- }
248
- }
249
-
250
- get startDate() {
251
- if (this.props.startDate) {
252
- return this.props.startDate;
253
- } else {
254
- return '1900-01-01';
255
- }
256
- }
257
-
258
- get endDate() {
259
- if (this.props.endDate) {
260
- return this.props.endDate;
261
- } else {
262
- return '9999-12-31';
263
- }
264
- }
265
-
266
- // Called when the '<' button is clicked.
267
- // Modify internalState.visibleDate (fix visible year and month).
268
- onPrevMonth() {
269
- const newDate = DateConverters.addMonths(this.visibleDate, -1);
270
- this.changeDate(newDate);
271
- }
272
-
273
- // Called when the '>' button is clicked.
274
- // Modify internalState.visibleDate (fix visible year and month).
275
- onNextMonth() {
276
- const newDate = DateConverters.addMonths(this.visibleDate, 1);
277
- this.changeDate(newDate);
278
- }
279
-
280
- onOpenComboMonths() {
281
- this.showComboMonths = true;
282
- }
283
-
284
- onOpenComboYears() {
285
- this.showComboYears = true;
286
- }
287
-
288
- onCloseComboMonths() {
289
- this.showComboMonths = false;
290
- }
291
-
292
- onCloseComboYears() {
293
- this.showComboYears = false;
294
- }
295
-
296
- onVisibleDateNow() {
297
- const now = DateConverters.getNowCanonical();
298
- const year = DateConverters.getYear(now);
299
- const month = DateConverters.getMonth(now);
300
- const date = DateConverters.getDate(year, month, 1);
301
- this.changeDate(date);
302
- }
303
-
304
- onVisibleDateMonth(month) {
305
- const s = DateConverters.split(this.visibleDate);
306
- const date = DateConverters.getDate(s.year, month, 1);
307
- this.changeDate(date);
308
- }
309
-
310
- onVisibleDateAddMonths(months) {
311
- const date = DateConverters.addMonths(this.visibleDate, months);
312
- this.changeDate(date);
313
- }
314
-
315
- onVisibleDatePrevYear() {
316
- const s = DateConverters.split(this.visibleDate);
317
- const year = s.month === 1 ? s.year - 1 : s.year;
318
- const date = DateConverters.getDate(year, 1, 1);
319
- this.changeDate(date);
320
- }
321
-
322
- onVisibleDateNextYear() {
323
- const s = DateConverters.split(this.visibleDate);
324
- const date = DateConverters.getDate(s.year + 1, 1, 1);
325
- this.changeDate(date);
326
- }
327
-
328
- onDateClicked(date) {
329
- if (
330
- date >= this.startDate &&
331
- date <= this.endDate &&
332
- !this.props.readonly
333
- ) {
334
- this.dateClicked(date);
335
- }
336
- }
337
-
338
- dateClicked(date) {
339
- const x = this.props.dateClicked;
340
- if (x) {
341
- x(date);
342
- }
343
- }
344
-
345
- onEscKey() {
346
- if (this.props.onEscKey) {
347
- this.props.onEscKey();
348
- }
349
- }
350
-
351
- handleWheel(e) {
352
- const inc = e.deltaY < 0 ? -1 : 1;
353
- const newDate = DateConverters.addMonths(this.visibleDate, inc);
354
- this.changeDate(newDate);
355
- }
356
-
357
- /******************************************************************************/
358
-
359
- // Return the html for a [1]..[31] button.
360
- renderButton(
361
- date,
362
- active,
363
- selected,
364
- dimmed,
365
- disabled,
366
- hidden,
367
- weekend,
368
- subkind,
369
- badgeValue,
370
- badgeColor,
371
- data,
372
- index
373
- ) {
374
- if (hidden) {
375
- return <div key={index} className={this.styles.classNames.button} />;
376
- }
377
-
378
- const tooltip = DateConverters.getDisplayed(date, 'Wdmy');
379
- let d = DateConverters.getDay(date); // 1..31
380
-
381
- const style =
382
- weekend && !dimmed
383
- ? this.styles.classNames.buttonWeekend
384
- : this.styles.classNames.button;
385
-
386
- if (this.props.itemComponent) {
387
- const Component = this.props.itemComponent;
388
- return (
389
- <div key={index} className={style}>
390
- <Component
391
- width={this.props.itemWidth}
392
- height={this.props.itemHeight}
393
- text={d}
394
- tooltip={tooltip}
395
- dimmed={dimmed}
396
- disabled={disabled}
397
- selected={selected}
398
- hover={this.props.hoverDates ? this.props.hoverDates[date] : null}
399
- date={date}
400
- data={data}
401
- onMouseOver={
402
- dimmed || !this.props.dateEntered ? null : this.props.dateEntered
403
- }
404
- onMouseMove={
405
- dimmed || !this.props.dateMoved ? null : this.props.dateMoved
406
- }
407
- onMouseOut={
408
- dimmed || !this.props.dateLeaved ? null : this.props.dateLeaved
409
- }
410
- onClick={dimmed ? null : () => this.onDateClicked(date)}
411
- />
412
- </div>
413
- );
414
- } else {
415
- if (subkind === 'sub') {
416
- d = '(' + d + ')';
417
- }
418
-
419
- return (
420
- <div key={index} className={style}>
421
- <CalendarButton
422
- text={d}
423
- tooltip={tooltip}
424
- subkind={subkind}
425
- active={active}
426
- dimmed={dimmed}
427
- disabled={disabled}
428
- selected={selected}
429
- badgePosition="top-right"
430
- badgeValue={badgeValue}
431
- badgeColor={badgeColor}
432
- badgeShape="circle"
433
- badgeSize="0.8"
434
- onClick={() => this.onDateClicked(date)}
435
- />
436
- </div>
437
- );
438
- }
439
- }
440
-
441
- // Return an array of 7 buttons, for a week.
442
- renderButtons(startOfMonth, firstDate) {
443
- const startVisibleDate = this.startVisibleDate;
444
- const endVisibleDate = this.endVisibleDate;
445
- const line = [];
446
- let i = 0;
447
- for (i = 0; i < 7; ++i) {
448
- // monday..sunday
449
- let active = false;
450
- let selected = false;
451
- let dimmed = false;
452
- let disabled = false;
453
- let hidden = false;
454
- let weekend = false;
455
- let subkind = null;
456
-
457
- let badgeValue = this.getBadgeValue(firstDate);
458
- let badgeColor = this.getBadgeColor(firstDate);
459
-
460
- const data = this.getDateData(firstDate);
461
-
462
- if (firstDate === this.props.selectedDate) {
463
- selected = true;
464
- }
465
-
466
- if (data) {
467
- active = true;
468
- subkind = data.type;
469
- }
470
-
471
- if (
472
- DateConverters.getYear(firstDate) !==
473
- DateConverters.getYear(startOfMonth) ||
474
- DateConverters.getMonth(firstDate) !==
475
- DateConverters.getMonth(startOfMonth)
476
- ) {
477
- dimmed = true;
478
- if (this.props.hideDaysOutOfMonth) {
479
- hidden = true;
480
- }
481
- }
482
- if (firstDate < this.startDate || firstDate > this.endDate) {
483
- disabled = true;
484
- }
485
- if (i >= 5) {
486
- // saturday or sunday ?
487
- weekend = true;
488
- }
489
- if (firstDate < startVisibleDate || firstDate > endVisibleDate) {
490
- dimmed = true;
491
- }
492
-
493
- const button = this.renderButton(
494
- firstDate,
495
- active,
496
- selected,
497
- dimmed,
498
- disabled,
499
- hidden,
500
- weekend,
501
- subkind,
502
- badgeValue,
503
- badgeColor,
504
- data,
505
- i
506
- );
507
- line.push(button);
508
- firstDate = DateConverters.addDays(firstDate, 1);
509
- }
510
- return line;
511
- }
512
-
513
- // Return the html for a line of 7 buttons (for a week).
514
- renderLineOfButtons(startOfMonth, firstDate, index) {
515
- return (
516
- <div className={this.styles.classNames.line} key={index}>
517
- {this.renderButtons(startOfMonth, firstDate)}
518
- </div>
519
- );
520
- }
521
-
522
- renderPrevMonthButton(showing) {
523
- if (showing) {
524
- return (
525
- <Button
526
- glyph="solid/chevron-left"
527
- kind="calendar-navigator"
528
- key="prevMonth"
529
- disabled={this.visibleDate < this.startDate}
530
- onClick={this.onPrevMonth}
531
- />
532
- );
533
- } else {
534
- return null;
535
- }
536
- }
537
-
538
- renderTitleButton(headerMonth, headerYear) {
539
- return (
540
- <>
541
- <div className={this.styles.classNames.headerTitleSajex} />
542
- <div ref={this.setRefMonths}>
543
- <Button
544
- kind="calendar-title"
545
- text={headerMonth}
546
- active={this.showComboMonths}
547
- onClick={this.onOpenComboMonths}
548
- />
549
- </div>
550
- <div ref={this.setRefYears}>
551
- <Button
552
- kind="calendar-title"
553
- text={headerYear}
554
- active={this.showComboYears}
555
- onClick={this.onOpenComboYears}
556
- />
557
- </div>
558
- <div className={this.styles.classNames.headerTitleSajex} />
559
- </>
560
- );
561
- }
562
-
563
- renderNextMonthButton(showing) {
564
- if (showing) {
565
- return (
566
- <Button
567
- glyph="solid/chevron-right"
568
- kind="calendar-navigator"
569
- key="nextMonth"
570
- disabled={
571
- DateConverters.moveAtEndingOfMonth(this.visibleDate) >= this.endDate
572
- }
573
- onClick={this.onNextMonth}
574
- />
575
- );
576
- } else {
577
- return null;
578
- }
579
- }
580
-
581
- // Return the html for the header, with 2 buttons next/prevMonth and the title.
582
- // By example: '<' mai 2016 '>'
583
- renderHeader(headerMonth, headerYear, isFirstMonth, isLastMonth) {
584
- return (
585
- <div className={this.styles.classNames.header} key="header">
586
- {this.renderPrevMonthButton(isFirstMonth)}
587
- {this.renderTitleButton(headerMonth, headerYear)}
588
- {this.renderNextMonthButton(isLastMonth)}
589
- </div>
590
- );
591
- }
592
-
593
- // Return the html for a [lun]..[dim] labels.
594
- renderDOW(text, index) {
595
- return (
596
- <div className={this.styles.classNames.dowText} key={index}>
597
- <Label insideButton={true} kind="compact" text={text} />
598
- </div>
599
- );
600
- }
601
-
602
- // Return an array of 7 days of week.
603
- renderDOWs() {
604
- const line = [];
605
- let i = 0;
606
- for (i = 0; i < 7; i++) {
607
- const dow = this.getDOW3Letters(i + 1);
608
- line.push(this.renderDOW(dow, i));
609
- }
610
- return line;
611
- }
612
-
613
- // Return the html for the 7 days of week header.
614
- renderLineOfDOWs() {
615
- return (
616
- <div className={this.styles.classNames.dowLine} key="dows">
617
- {this.renderDOWs()}
618
- </div>
619
- );
620
- }
621
-
622
- // Return an array of lines, with header then week's lines.
623
- // The array must have from 4 to 6 lines.
624
- renderColumnOfLines(
625
- headerMonth,
626
- headerYear,
627
- startOfMonth,
628
- firstDate,
629
- isFirstMonth,
630
- isLastMonth
631
- ) {
632
- const column = [];
633
- column.push(
634
- this.renderHeader(headerMonth, headerYear, isFirstMonth, isLastMonth)
635
- );
636
- column.push(this.renderLineOfDOWs());
637
- for (let i = 0; i < 6; ++i) {
638
- const line = this.renderLineOfButtons(startOfMonth, firstDate, i);
639
- column.push(line);
640
- firstDate = DateConverters.addDays(firstDate, 7);
641
- }
642
- return column;
643
- }
644
-
645
- // Return all the html content of the calendar.
646
- renderLines(startOfMonth, isFirstMonth, isLastMonth) {
647
- const firstDate = DateConverters.getCalendarStartDate(startOfMonth);
648
- const headerMonth = DateConverters.getDisplayed(startOfMonth, 'M'); // 'mai' by example
649
- const headerYear = DateConverters.getDisplayed(startOfMonth, 'y'); // '2016' by example
650
-
651
- return (
652
- <div className={this.styles.classNames.column}>
653
- {this.renderColumnOfLines(
654
- headerMonth,
655
- headerYear,
656
- startOfMonth,
657
- firstDate,
658
- isFirstMonth,
659
- isLastMonth
660
- )}
661
- </div>
662
- );
663
- }
664
-
665
- renderMonth(startOfMonth, isFirstMonth, isLastMonth, index) {
666
- const monthClass = isLastMonth
667
- ? this.styles.classNames.singleMonth
668
- : this.styles.classNames.month;
669
-
670
- return (
671
- <div className={monthClass} key={index}>
672
- {this.renderLines(startOfMonth, isFirstMonth, isLastMonth)}
673
- </div>
674
- );
675
- }
676
-
677
- renderSeparator(index) {
678
- return <div className={this.styles.classNames.separator} key={index} />;
679
- }
680
-
681
- renderMonths() {
682
- const result = [];
683
- const monthCount = this.monthCount;
684
- let index = 0;
685
- for (var m = 0; m < monthCount; m++) {
686
- const year = DateConverters.getYear(this.visibleDate);
687
- const month = DateConverters.getMonth(this.visibleDate);
688
- const startOfMonth = DateConverters.getDate(year, month + m, 1);
689
-
690
- const isFirstMonth = m === 0;
691
- const isLastMonth = m === monthCount - 1;
692
- result.push(
693
- this.renderMonth(startOfMonth, isFirstMonth, isLastMonth, index++)
694
- );
695
- if (monthCount > 1 && !isLastMonth) {
696
- result.push(this.renderSeparator(index++));
697
- }
698
- }
699
- return result;
700
- }
701
-
702
- renderQuickMonth(month, visibleMonth) {
703
- const firstVisibleMonth = visibleMonth;
704
- const lastVisibleMonth = visibleMonth + this.monthCount;
705
- const active = month >= firstVisibleMonth && month < lastVisibleMonth;
706
- return (
707
- <Button
708
- text={MonthConverters.getDisplayed(month, 'one-letter')}
709
- tooltip={MonthConverters.getDisplayed(month)}
710
- kind="calendar-navigator"
711
- grow="1"
712
- onClick={() => this.onVisibleDateMonth(month)}
713
- active={active}
714
- horizontalSpacing="tiny"
715
- />
716
- );
717
- }
718
-
719
- renderLineOfMonths(month, visibleMonth) {
720
- return (
721
- <div className={this.styles.classNames.double} key={month}>
722
- {this.renderQuickMonth(month + 0, visibleMonth)}
723
- {this.renderQuickMonth(month + 1, visibleMonth)}
724
- {this.renderQuickMonth(month + 2, visibleMonth)}
725
- {this.renderQuickMonth(month + 3, visibleMonth)}
726
- </div>
727
- );
728
- }
729
-
730
- renderMonthsOfYear() {
731
- const result = [];
732
- const visibleMonth = DateConverters.split(this.visibleDate).month;
733
- for (let month = 1; month <= 12; month += 4) {
734
- result.push(this.renderLineOfMonths(month, visibleMonth));
735
- }
736
- return result;
737
- }
738
-
739
- renderPrevNext(title, leftGlyph, rightGlyph, leftAction, rightAction) {
740
- return (
741
- <div className={this.styles.classNames.double}>
742
- <Button
743
- glyph={leftGlyph}
744
- kind="calendar-navigator"
745
- onClick={leftAction}
746
- />
747
- <Label text={title} grow="1" justify="center" />
748
- <Button
749
- glyph={rightGlyph}
750
- kind="calendar-navigator"
751
- onClick={rightAction}
752
- />
753
- </div>
754
- );
755
- }
756
-
757
- renderNavigatorMonths() {
758
- const monthCount = this.monthCount;
759
- if (monthCount > 1) {
760
- return this.renderPrevNext(
761
- T(`{monthCount} mois`, '', {monthCount}),
762
- 'solid/chevron-left',
763
- 'solid/chevron-right',
764
- () => this.onVisibleDateAddMonths(-monthCount),
765
- () => this.onVisibleDateAddMonths(monthCount)
766
- );
767
- } else {
768
- return null;
769
- }
770
- }
771
-
772
- renderNavigator() {
773
- const navigator = this.props.navigator;
774
- if (navigator === 'standard') {
775
- return (
776
- <div className={this.styles.classNames.navigator}>
777
- {this.renderNavigatorMonths()}
778
- <Separator kind="space" height="20px" />
779
- {this.renderMonthsOfYear()}
780
- <Separator kind="space" height="20px" />
781
- {this.renderPrevNext(
782
- T('année'),
783
- 'solid/step-backward',
784
- 'solid/step-forward',
785
- this.onVisibleDatePrevYear,
786
- this.onVisibleDateNextYear
787
- )}
788
- </div>
789
- );
790
- } else {
791
- return null;
792
- }
793
- }
794
-
795
- renderTips() {
796
- if (!this.props.useTips) {
797
- return null;
798
- }
799
-
800
- // prettier-ignore
801
- const tips = [
802
- T("Cliquez en haut sur le nom du mois ou sur l'année pour changer rapidement le mois visible."),
803
- T('Utilisez la molette de la souris pour avancer ou reculer dans les mois.'),
804
- ];
805
-
806
- return (
807
- <div
808
- className={
809
- this.props.showTips
810
- ? this.styles.classNames.tipsShowed
811
- : this.styles.classNames.tipsHidden
812
- }
813
- >
814
- <Tips
815
- grow={1}
816
- height={this.props.showTips ? '55px' : '0px'}
817
- layout="horizontal"
818
- id="goblin-gadgets/calendar"
819
- tips={tips}
820
- />
821
- </div>
822
- );
823
- }
824
-
825
- renderComboMonths() {
826
- return (
827
- <ComboContainer
828
- show={this.showComboMonths}
829
- positionRef={this.nodeMonths}
830
- onClose={this.onCloseComboMonths}
831
- >
832
- <FlatList
833
- menuItemWidth="160px"
834
- list={this.comboMonthsList}
835
- selectedId={this.props.visibleDate}
836
- onChange={this.onComboMonthsClicked}
837
- onEscKey={this.onCloseComboMonths}
838
- />
839
- </ComboContainer>
840
- );
841
- }
842
-
843
- renderComboYears() {
844
- return (
845
- <ComboContainer
846
- show={this.showComboYears}
847
- positionRef={this.nodeYears}
848
- onClose={this.onCloseComboYears}
849
- >
850
- <FlatList
851
- menuItemWidth="120px"
852
- list={this.comboYearsList}
853
- selectedId={this.props.visibleDate}
854
- onChange={this.onComboYearsClicked}
855
- onEscKey={this.onCloseComboYears}
856
- />
857
- </ComboContainer>
858
- );
859
- }
860
-
861
- render() {
862
- if (!this.props.visibleDate) {
863
- return null;
864
- }
865
-
866
- return (
867
- <div
868
- className={
869
- this.props.showTips
870
- ? this.styles.classNames.calendarTips
871
- : this.styles.classNames.calendar
872
- }
873
- onWheel={(e) => this.handleWheel(e)}
874
- >
875
- {this.renderMonths()}
876
- {this.renderTips()}
877
- {this.renderNavigator()}
878
- {this.renderComboMonths()}
879
- {this.renderComboYears()}
880
- </div>
881
- );
882
- }
883
- }
884
-
885
- /******************************************************************************/
886
-
887
- export default Widget.connect((state, props) => {
888
- const userSession = Widget.getUserSession(state);
889
- const data = userSession.get('tips.goblin-gadgets/calendar');
890
- const tipsRank = data ? data.get('rank') : 0; // show first tip if state never defined
891
-
892
- return {showTips: props.useTips && tipsRank !== -1};
893
- })(Calendar);
894
-
895
- registerWidget(Calendar, props, scenarios);
1
+ import T from 't';
2
+ import React from 'react';
3
+ import props from './props';
4
+ import scenarios from './scenarios';
5
+ import {registerWidget} from 'goblin-gadgets/widgets/widget-doc/widget-list';
6
+ import Widget from 'goblin-laboratory/widgets/widget';
7
+ import KeyTrap from 'goblin-gadgets/widgets/key-trap.js';
8
+
9
+ import Label from 'goblin-gadgets/widgets/label/widget';
10
+ import Button from 'goblin-gadgets/widgets/button/widget';
11
+ import CalendarButton from 'goblin-gadgets/widgets/calendar-button/widget';
12
+ import Separator from 'goblin-gadgets/widgets/separator/widget';
13
+ import ComboContainer from 'goblin-gadgets/widgets/combo-container/widget';
14
+ import FlatList from 'goblin-gadgets/widgets/flat-list/widget';
15
+ import Tips from 'goblin-gadgets/widgets/tips/widget';
16
+
17
+ import {
18
+ date as DateConverters,
19
+ month as MonthConverters,
20
+ dow as DowConverters,
21
+ } from 'xcraft-core-converters';
22
+ import * as styles from './styles';
23
+
24
+ /******************************************************************************/
25
+
26
+ class Calendar extends Widget {
27
+ constructor() {
28
+ super(...arguments);
29
+ this.styles = styles;
30
+
31
+ this.state = {
32
+ showComboMonths: false,
33
+ showComboYears: false,
34
+ visibleDate: null,
35
+ };
36
+
37
+ this.setRefMonths = this.setRefMonths.bind(this);
38
+ this.setRefYears = this.setRefYears.bind(this);
39
+ this.onPrevMonth = this.onPrevMonth.bind(this);
40
+ this.onNextMonth = this.onNextMonth.bind(this);
41
+ this.onOpenComboMonths = this.onOpenComboMonths.bind(this);
42
+ this.onOpenComboYears = this.onOpenComboYears.bind(this);
43
+ this.onCloseComboMonths = this.onCloseComboMonths.bind(this);
44
+ this.onCloseComboYears = this.onCloseComboYears.bind(this);
45
+ this.onComboMonthsClicked = this.onComboMonthsClicked.bind(this);
46
+ this.onComboYearsClicked = this.onComboYearsClicked.bind(this);
47
+ this.onVisibleDateMonth = this.onVisibleDateMonth.bind(this);
48
+ this.onVisibleDateAddMonths = this.onVisibleDateAddMonths.bind(this);
49
+ this.onVisibleDatePrevYear = this.onVisibleDatePrevYear.bind(this);
50
+ this.onVisibleDateNextYear = this.onVisibleDateNextYear.bind(this);
51
+ this.onDateClicked = this.onDateClicked.bind(this);
52
+ this.onEscKey = this.onEscKey.bind(this);
53
+ this.handleWheel = this.handleWheel.bind(this);
54
+ }
55
+
56
+ //#region get/set
57
+ get showComboMonths() {
58
+ return this.state.showComboMonths;
59
+ }
60
+
61
+ set showComboMonths(value) {
62
+ this.setState({
63
+ showComboMonths: value,
64
+ });
65
+ }
66
+
67
+ get showComboYears() {
68
+ return this.state.showComboYears;
69
+ }
70
+
71
+ set showComboYears(value) {
72
+ this.setState({
73
+ showComboYears: value,
74
+ });
75
+ }
76
+
77
+ get visibleDate() {
78
+ return this.state.visibleDate || this.props.visibleDate;
79
+ }
80
+
81
+ set visibleDate(value) {
82
+ this.setState({
83
+ visibleDate: value,
84
+ });
85
+ }
86
+ //#endregion
87
+
88
+ static get wiring() {
89
+ return {
90
+ id: 'id',
91
+ msg: 'msg',
92
+ };
93
+ }
94
+
95
+ /******************************************************************************/
96
+
97
+ UNSAFE_componentWillMount() {
98
+ if (this.props.onEscKey) {
99
+ KeyTrap.bind('Escape', this.onEscKey);
100
+ }
101
+ }
102
+
103
+ componentWillUnmount() {
104
+ super.componentWillUnmount();
105
+ if (this.props.onEscKey) {
106
+ KeyTrap.unbind('Escape', this.onEscKey);
107
+ }
108
+ }
109
+
110
+ /******************************************************************************/
111
+
112
+ setRefMonths(node) {
113
+ this.nodeMonths = node;
114
+ }
115
+
116
+ setRefYears(node) {
117
+ this.nodeYears = node;
118
+ }
119
+
120
+ onComboMonthsClicked(item) {
121
+ this.onCloseComboMonths();
122
+ this.changeDate(item.id);
123
+ //? this.dateClicked(item.id);
124
+ }
125
+
126
+ onComboYearsClicked(item) {
127
+ this.onCloseComboYears();
128
+ this.changeDate(item.id);
129
+ //? this.dateClicked(item.id);
130
+ }
131
+
132
+ get comboMonthsList() {
133
+ const list = [];
134
+ const year = DateConverters.getYear(this.visibleDate);
135
+ const day = DateConverters.getDay(this.visibleDate);
136
+ const isLast =
137
+ this.visibleDate === DateConverters.moveAtEndingOfMonth(this.visibleDate);
138
+ for (let month = 1; month <= 12; month++) {
139
+ const date = DateConverters.getDate(year, month, isLast ? 31 : day, true);
140
+ list.push({
141
+ id: date,
142
+ text: DateConverters.getDisplayed(date, 'M'),
143
+ isLast,
144
+ });
145
+ }
146
+ return list;
147
+ }
148
+
149
+ get comboYearsList() {
150
+ const list = [];
151
+ const nowRank = DateConverters.getYear(this.visibleDate);
152
+ const month = DateConverters.getMonth(this.visibleDate);
153
+ const day = DateConverters.getDay(this.visibleDate);
154
+ const startCount = Math.max(
155
+ this.props.startDate
156
+ ? DateConverters.getYear(this.props.startDate) - nowRank
157
+ : -999,
158
+ -10
159
+ );
160
+ const endCount = Math.min(
161
+ this.props.endDate
162
+ ? DateConverters.getYear(this.props.endDate) - nowRank
163
+ : 999,
164
+ 10
165
+ );
166
+ for (let i = startCount; i <= endCount; i++) {
167
+ const date = DateConverters.getDate(nowRank + i, month, day, true);
168
+ list.push({
169
+ id: date,
170
+ text: DateConverters.getDisplayed(date, 'y'),
171
+ });
172
+ }
173
+ return list;
174
+ }
175
+
176
+ getDateData(date) {
177
+ if (!this.props.dates || this.props.dates.length === 0) {
178
+ return null;
179
+ } else if (typeof this.props.dates[0] === 'string') {
180
+ return this.props.dates.indexOf(date) === -1 ? null : {type: 'base'};
181
+ } else if (Array.isArray(this.props.dates)) {
182
+ for (const d of this.props.dates) {
183
+ if (d.date === date) {
184
+ return d;
185
+ }
186
+ }
187
+ return null;
188
+ } else {
189
+ return this.props.dates[date];
190
+ }
191
+ }
192
+
193
+ getBadgeValue(date) {
194
+ if (!this.props.badges || this.props.badges.length === 0) {
195
+ return 0;
196
+ } else {
197
+ for (const badge of this.props.badges) {
198
+ if (badge.date === date) {
199
+ return badge.value;
200
+ }
201
+ }
202
+ return 0;
203
+ }
204
+ }
205
+
206
+ getBadgeColor(date) {
207
+ if (!this.props.badges || this.props.badges.length === 0) {
208
+ return null;
209
+ } else {
210
+ for (const badge of this.props.badges) {
211
+ if (badge.date === date) {
212
+ return badge.color;
213
+ }
214
+ }
215
+ return null;
216
+ }
217
+ }
218
+
219
+ get startVisibleDate() {
220
+ const month = DateConverters.getMonth(this.visibleDate);
221
+ const year = DateConverters.getYear(this.visibleDate);
222
+ return DateConverters.getDate(year, month, 1);
223
+ }
224
+
225
+ get endVisibleDate() {
226
+ return DateConverters.addDays(
227
+ DateConverters.addMonths(this.startVisibleDate, this.monthCount),
228
+ -1
229
+ );
230
+ }
231
+
232
+ get monthCount() {
233
+ const monthCount = this.props.monthCount;
234
+ return monthCount ? Math.min(parseInt(monthCount), 12) : 1;
235
+ }
236
+
237
+ getDOW3Letters(dow) {
238
+ return DowConverters.getDisplayed(dow, 'short');
239
+ }
240
+
241
+ changeDate(date) {
242
+ this.visibleDate = date;
243
+
244
+ const x = this.props.visibleDateChanged;
245
+ if (x) {
246
+ x(date);
247
+ }
248
+ }
249
+
250
+ get startDate() {
251
+ if (this.props.startDate) {
252
+ return this.props.startDate;
253
+ } else {
254
+ return '1900-01-01';
255
+ }
256
+ }
257
+
258
+ get endDate() {
259
+ if (this.props.endDate) {
260
+ return this.props.endDate;
261
+ } else {
262
+ return '9999-12-31';
263
+ }
264
+ }
265
+
266
+ // Called when the '<' button is clicked.
267
+ // Modify internalState.visibleDate (fix visible year and month).
268
+ onPrevMonth() {
269
+ const newDate = DateConverters.addMonths(this.visibleDate, -1);
270
+ this.changeDate(newDate);
271
+ }
272
+
273
+ // Called when the '>' button is clicked.
274
+ // Modify internalState.visibleDate (fix visible year and month).
275
+ onNextMonth() {
276
+ const newDate = DateConverters.addMonths(this.visibleDate, 1);
277
+ this.changeDate(newDate);
278
+ }
279
+
280
+ onOpenComboMonths() {
281
+ this.showComboMonths = true;
282
+ }
283
+
284
+ onOpenComboYears() {
285
+ this.showComboYears = true;
286
+ }
287
+
288
+ onCloseComboMonths() {
289
+ this.showComboMonths = false;
290
+ }
291
+
292
+ onCloseComboYears() {
293
+ this.showComboYears = false;
294
+ }
295
+
296
+ onVisibleDateNow() {
297
+ const now = DateConverters.getNowCanonical();
298
+ const year = DateConverters.getYear(now);
299
+ const month = DateConverters.getMonth(now);
300
+ const date = DateConverters.getDate(year, month, 1);
301
+ this.changeDate(date);
302
+ }
303
+
304
+ onVisibleDateMonth(month) {
305
+ const s = DateConverters.split(this.visibleDate);
306
+ const date = DateConverters.getDate(s.year, month, 1);
307
+ this.changeDate(date);
308
+ }
309
+
310
+ onVisibleDateAddMonths(months) {
311
+ const date = DateConverters.addMonths(this.visibleDate, months);
312
+ this.changeDate(date);
313
+ }
314
+
315
+ onVisibleDatePrevYear() {
316
+ const s = DateConverters.split(this.visibleDate);
317
+ const year = s.month === 1 ? s.year - 1 : s.year;
318
+ const date = DateConverters.getDate(year, 1, 1);
319
+ this.changeDate(date);
320
+ }
321
+
322
+ onVisibleDateNextYear() {
323
+ const s = DateConverters.split(this.visibleDate);
324
+ const date = DateConverters.getDate(s.year + 1, 1, 1);
325
+ this.changeDate(date);
326
+ }
327
+
328
+ onDateClicked(date) {
329
+ if (
330
+ date >= this.startDate &&
331
+ date <= this.endDate &&
332
+ !this.props.readonly
333
+ ) {
334
+ this.dateClicked(date);
335
+ }
336
+ }
337
+
338
+ dateClicked(date) {
339
+ const x = this.props.dateClicked;
340
+ if (x) {
341
+ x(date);
342
+ }
343
+ }
344
+
345
+ onEscKey() {
346
+ if (this.props.onEscKey) {
347
+ this.props.onEscKey();
348
+ }
349
+ }
350
+
351
+ handleWheel(e) {
352
+ const inc = e.deltaY < 0 ? -1 : 1;
353
+ const newDate = DateConverters.addMonths(this.visibleDate, inc);
354
+ this.changeDate(newDate);
355
+ }
356
+
357
+ /******************************************************************************/
358
+
359
+ // Return the html for a [1]..[31] button.
360
+ renderButton(
361
+ date,
362
+ active,
363
+ selected,
364
+ dimmed,
365
+ disabled,
366
+ hidden,
367
+ weekend,
368
+ subkind,
369
+ badgeValue,
370
+ badgeColor,
371
+ data,
372
+ index
373
+ ) {
374
+ if (hidden) {
375
+ return <div key={index} className={this.styles.classNames.button} />;
376
+ }
377
+
378
+ const tooltip = DateConverters.getDisplayed(date, 'Wdmy');
379
+ let d = DateConverters.getDay(date); // 1..31
380
+
381
+ const style =
382
+ weekend && !dimmed
383
+ ? this.styles.classNames.buttonWeekend
384
+ : this.styles.classNames.button;
385
+
386
+ if (this.props.itemComponent) {
387
+ const Component = this.props.itemComponent;
388
+ return (
389
+ <div key={index} className={style}>
390
+ <Component
391
+ width={this.props.itemWidth}
392
+ height={this.props.itemHeight}
393
+ text={d}
394
+ tooltip={tooltip}
395
+ dimmed={dimmed}
396
+ disabled={disabled}
397
+ selected={selected}
398
+ hover={this.props.hoverDates ? this.props.hoverDates[date] : null}
399
+ date={date}
400
+ data={data}
401
+ onMouseOver={
402
+ dimmed || !this.props.dateEntered ? null : this.props.dateEntered
403
+ }
404
+ onMouseMove={
405
+ dimmed || !this.props.dateMoved ? null : this.props.dateMoved
406
+ }
407
+ onMouseOut={
408
+ dimmed || !this.props.dateLeaved ? null : this.props.dateLeaved
409
+ }
410
+ onClick={dimmed ? null : () => this.onDateClicked(date)}
411
+ />
412
+ </div>
413
+ );
414
+ } else {
415
+ if (subkind === 'sub') {
416
+ d = '(' + d + ')';
417
+ }
418
+
419
+ return (
420
+ <div key={index} className={style}>
421
+ <CalendarButton
422
+ text={d}
423
+ tooltip={tooltip}
424
+ subkind={subkind}
425
+ active={active}
426
+ dimmed={dimmed}
427
+ disabled={disabled}
428
+ selected={selected}
429
+ badgePosition="top-right"
430
+ badgeValue={badgeValue}
431
+ badgeColor={badgeColor}
432
+ badgeShape="circle"
433
+ badgeSize="0.8"
434
+ onClick={() => this.onDateClicked(date)}
435
+ />
436
+ </div>
437
+ );
438
+ }
439
+ }
440
+
441
+ // Return an array of 7 buttons, for a week.
442
+ renderButtons(startOfMonth, firstDate) {
443
+ const startVisibleDate = this.startVisibleDate;
444
+ const endVisibleDate = this.endVisibleDate;
445
+ const line = [];
446
+ let i = 0;
447
+ for (i = 0; i < 7; ++i) {
448
+ // monday..sunday
449
+ let active = false;
450
+ let selected = false;
451
+ let dimmed = false;
452
+ let disabled = false;
453
+ let hidden = false;
454
+ let weekend = false;
455
+ let subkind = null;
456
+
457
+ let badgeValue = this.getBadgeValue(firstDate);
458
+ let badgeColor = this.getBadgeColor(firstDate);
459
+
460
+ const data = this.getDateData(firstDate);
461
+
462
+ if (firstDate === this.props.selectedDate) {
463
+ selected = true;
464
+ }
465
+
466
+ if (data) {
467
+ active = true;
468
+ subkind = data.type;
469
+ }
470
+
471
+ if (
472
+ DateConverters.getYear(firstDate) !==
473
+ DateConverters.getYear(startOfMonth) ||
474
+ DateConverters.getMonth(firstDate) !==
475
+ DateConverters.getMonth(startOfMonth)
476
+ ) {
477
+ dimmed = true;
478
+ if (this.props.hideDaysOutOfMonth) {
479
+ hidden = true;
480
+ }
481
+ }
482
+ if (firstDate < this.startDate || firstDate > this.endDate) {
483
+ disabled = true;
484
+ }
485
+ if (i >= 5) {
486
+ // saturday or sunday ?
487
+ weekend = true;
488
+ }
489
+ if (firstDate < startVisibleDate || firstDate > endVisibleDate) {
490
+ dimmed = true;
491
+ }
492
+
493
+ const button = this.renderButton(
494
+ firstDate,
495
+ active,
496
+ selected,
497
+ dimmed,
498
+ disabled,
499
+ hidden,
500
+ weekend,
501
+ subkind,
502
+ badgeValue,
503
+ badgeColor,
504
+ data,
505
+ i
506
+ );
507
+ line.push(button);
508
+ firstDate = DateConverters.addDays(firstDate, 1);
509
+ }
510
+ return line;
511
+ }
512
+
513
+ // Return the html for a line of 7 buttons (for a week).
514
+ renderLineOfButtons(startOfMonth, firstDate, index) {
515
+ return (
516
+ <div className={this.styles.classNames.line} key={index}>
517
+ {this.renderButtons(startOfMonth, firstDate)}
518
+ </div>
519
+ );
520
+ }
521
+
522
+ renderPrevMonthButton(showing) {
523
+ if (showing) {
524
+ return (
525
+ <Button
526
+ glyph="solid/chevron-left"
527
+ kind="calendar-navigator"
528
+ key="prevMonth"
529
+ disabled={this.visibleDate < this.startDate}
530
+ onClick={this.onPrevMonth}
531
+ />
532
+ );
533
+ } else {
534
+ return null;
535
+ }
536
+ }
537
+
538
+ renderTitleButton(headerMonth, headerYear) {
539
+ return (
540
+ <>
541
+ <div className={this.styles.classNames.headerTitleSajex} />
542
+ <div ref={this.setRefMonths}>
543
+ <Button
544
+ kind="calendar-title"
545
+ text={headerMonth}
546
+ active={this.showComboMonths}
547
+ onClick={this.onOpenComboMonths}
548
+ />
549
+ </div>
550
+ <div ref={this.setRefYears}>
551
+ <Button
552
+ kind="calendar-title"
553
+ text={headerYear}
554
+ active={this.showComboYears}
555
+ onClick={this.onOpenComboYears}
556
+ />
557
+ </div>
558
+ <div className={this.styles.classNames.headerTitleSajex} />
559
+ </>
560
+ );
561
+ }
562
+
563
+ renderNextMonthButton(showing) {
564
+ if (showing) {
565
+ return (
566
+ <Button
567
+ glyph="solid/chevron-right"
568
+ kind="calendar-navigator"
569
+ key="nextMonth"
570
+ disabled={
571
+ DateConverters.moveAtEndingOfMonth(this.visibleDate) >= this.endDate
572
+ }
573
+ onClick={this.onNextMonth}
574
+ />
575
+ );
576
+ } else {
577
+ return null;
578
+ }
579
+ }
580
+
581
+ // Return the html for the header, with 2 buttons next/prevMonth and the title.
582
+ // By example: '<' mai 2016 '>'
583
+ renderHeader(headerMonth, headerYear, isFirstMonth, isLastMonth) {
584
+ return (
585
+ <div className={this.styles.classNames.header} key="header">
586
+ {this.renderPrevMonthButton(isFirstMonth)}
587
+ {this.renderTitleButton(headerMonth, headerYear)}
588
+ {this.renderNextMonthButton(isLastMonth)}
589
+ </div>
590
+ );
591
+ }
592
+
593
+ // Return the html for a [lun]..[dim] labels.
594
+ renderDOW(text, index) {
595
+ return (
596
+ <div className={this.styles.classNames.dowText} key={index}>
597
+ <Label insideButton={true} kind="compact" text={text} />
598
+ </div>
599
+ );
600
+ }
601
+
602
+ // Return an array of 7 days of week.
603
+ renderDOWs() {
604
+ const line = [];
605
+ let i = 0;
606
+ for (i = 0; i < 7; i++) {
607
+ const dow = this.getDOW3Letters(i + 1);
608
+ line.push(this.renderDOW(dow, i));
609
+ }
610
+ return line;
611
+ }
612
+
613
+ // Return the html for the 7 days of week header.
614
+ renderLineOfDOWs() {
615
+ return (
616
+ <div className={this.styles.classNames.dowLine} key="dows">
617
+ {this.renderDOWs()}
618
+ </div>
619
+ );
620
+ }
621
+
622
+ // Return an array of lines, with header then week's lines.
623
+ // The array must have from 4 to 6 lines.
624
+ renderColumnOfLines(
625
+ headerMonth,
626
+ headerYear,
627
+ startOfMonth,
628
+ firstDate,
629
+ isFirstMonth,
630
+ isLastMonth
631
+ ) {
632
+ const column = [];
633
+ column.push(
634
+ this.renderHeader(headerMonth, headerYear, isFirstMonth, isLastMonth)
635
+ );
636
+ column.push(this.renderLineOfDOWs());
637
+ for (let i = 0; i < 6; ++i) {
638
+ const line = this.renderLineOfButtons(startOfMonth, firstDate, i);
639
+ column.push(line);
640
+ firstDate = DateConverters.addDays(firstDate, 7);
641
+ }
642
+ return column;
643
+ }
644
+
645
+ // Return all the html content of the calendar.
646
+ renderLines(startOfMonth, isFirstMonth, isLastMonth) {
647
+ const firstDate = DateConverters.getCalendarStartDate(startOfMonth);
648
+ const headerMonth = DateConverters.getDisplayed(startOfMonth, 'M'); // 'mai' by example
649
+ const headerYear = DateConverters.getDisplayed(startOfMonth, 'y'); // '2016' by example
650
+
651
+ return (
652
+ <div className={this.styles.classNames.column}>
653
+ {this.renderColumnOfLines(
654
+ headerMonth,
655
+ headerYear,
656
+ startOfMonth,
657
+ firstDate,
658
+ isFirstMonth,
659
+ isLastMonth
660
+ )}
661
+ </div>
662
+ );
663
+ }
664
+
665
+ renderMonth(startOfMonth, isFirstMonth, isLastMonth, index) {
666
+ const monthClass = isLastMonth
667
+ ? this.styles.classNames.singleMonth
668
+ : this.styles.classNames.month;
669
+
670
+ return (
671
+ <div className={monthClass} key={index}>
672
+ {this.renderLines(startOfMonth, isFirstMonth, isLastMonth)}
673
+ </div>
674
+ );
675
+ }
676
+
677
+ renderSeparator(index) {
678
+ return <div className={this.styles.classNames.separator} key={index} />;
679
+ }
680
+
681
+ renderMonths() {
682
+ const result = [];
683
+ const monthCount = this.monthCount;
684
+ let index = 0;
685
+ for (var m = 0; m < monthCount; m++) {
686
+ const year = DateConverters.getYear(this.visibleDate);
687
+ const month = DateConverters.getMonth(this.visibleDate);
688
+ const startOfMonth = DateConverters.getDate(year, month + m, 1);
689
+
690
+ const isFirstMonth = m === 0;
691
+ const isLastMonth = m === monthCount - 1;
692
+ result.push(
693
+ this.renderMonth(startOfMonth, isFirstMonth, isLastMonth, index++)
694
+ );
695
+ if (monthCount > 1 && !isLastMonth) {
696
+ result.push(this.renderSeparator(index++));
697
+ }
698
+ }
699
+ return result;
700
+ }
701
+
702
+ renderQuickMonth(month, visibleMonth) {
703
+ const firstVisibleMonth = visibleMonth;
704
+ const lastVisibleMonth = visibleMonth + this.monthCount;
705
+ const active = month >= firstVisibleMonth && month < lastVisibleMonth;
706
+ return (
707
+ <Button
708
+ text={MonthConverters.getDisplayed(month, 'one-letter')}
709
+ tooltip={MonthConverters.getDisplayed(month)}
710
+ kind="calendar-navigator"
711
+ grow="1"
712
+ onClick={() => this.onVisibleDateMonth(month)}
713
+ active={active}
714
+ horizontalSpacing="tiny"
715
+ />
716
+ );
717
+ }
718
+
719
+ renderLineOfMonths(month, visibleMonth) {
720
+ return (
721
+ <div className={this.styles.classNames.double} key={month}>
722
+ {this.renderQuickMonth(month + 0, visibleMonth)}
723
+ {this.renderQuickMonth(month + 1, visibleMonth)}
724
+ {this.renderQuickMonth(month + 2, visibleMonth)}
725
+ {this.renderQuickMonth(month + 3, visibleMonth)}
726
+ </div>
727
+ );
728
+ }
729
+
730
+ renderMonthsOfYear() {
731
+ const result = [];
732
+ const visibleMonth = DateConverters.split(this.visibleDate).month;
733
+ for (let month = 1; month <= 12; month += 4) {
734
+ result.push(this.renderLineOfMonths(month, visibleMonth));
735
+ }
736
+ return result;
737
+ }
738
+
739
+ renderPrevNext(title, leftGlyph, rightGlyph, leftAction, rightAction) {
740
+ return (
741
+ <div className={this.styles.classNames.double}>
742
+ <Button
743
+ glyph={leftGlyph}
744
+ kind="calendar-navigator"
745
+ onClick={leftAction}
746
+ />
747
+ <Label text={title} grow="1" justify="center" />
748
+ <Button
749
+ glyph={rightGlyph}
750
+ kind="calendar-navigator"
751
+ onClick={rightAction}
752
+ />
753
+ </div>
754
+ );
755
+ }
756
+
757
+ renderNavigatorMonths() {
758
+ const monthCount = this.monthCount;
759
+ if (monthCount > 1) {
760
+ return this.renderPrevNext(
761
+ T(`{monthCount} mois`, '', {monthCount}),
762
+ 'solid/chevron-left',
763
+ 'solid/chevron-right',
764
+ () => this.onVisibleDateAddMonths(-monthCount),
765
+ () => this.onVisibleDateAddMonths(monthCount)
766
+ );
767
+ } else {
768
+ return null;
769
+ }
770
+ }
771
+
772
+ renderNavigator() {
773
+ const navigator = this.props.navigator;
774
+ if (navigator === 'standard') {
775
+ return (
776
+ <div className={this.styles.classNames.navigator}>
777
+ {this.renderNavigatorMonths()}
778
+ <Separator kind="space" height="20px" />
779
+ {this.renderMonthsOfYear()}
780
+ <Separator kind="space" height="20px" />
781
+ {this.renderPrevNext(
782
+ T('année'),
783
+ 'solid/step-backward',
784
+ 'solid/step-forward',
785
+ this.onVisibleDatePrevYear,
786
+ this.onVisibleDateNextYear
787
+ )}
788
+ </div>
789
+ );
790
+ } else {
791
+ return null;
792
+ }
793
+ }
794
+
795
+ renderTips() {
796
+ if (!this.props.useTips) {
797
+ return null;
798
+ }
799
+
800
+ // prettier-ignore
801
+ const tips = [
802
+ T("Cliquez en haut sur le nom du mois ou sur l'année pour changer rapidement le mois visible."),
803
+ T('Utilisez la molette de la souris pour avancer ou reculer dans les mois.'),
804
+ ];
805
+
806
+ return (
807
+ <div
808
+ className={
809
+ this.props.showTips
810
+ ? this.styles.classNames.tipsShowed
811
+ : this.styles.classNames.tipsHidden
812
+ }
813
+ >
814
+ <Tips
815
+ grow={1}
816
+ height={this.props.showTips ? '55px' : '0px'}
817
+ layout="horizontal"
818
+ id="goblin-gadgets/calendar"
819
+ tips={tips}
820
+ />
821
+ </div>
822
+ );
823
+ }
824
+
825
+ renderComboMonths() {
826
+ return (
827
+ <ComboContainer
828
+ show={this.showComboMonths}
829
+ positionRef={this.nodeMonths}
830
+ onClose={this.onCloseComboMonths}
831
+ >
832
+ <FlatList
833
+ menuItemWidth="160px"
834
+ list={this.comboMonthsList}
835
+ selectedId={this.props.visibleDate}
836
+ onChange={this.onComboMonthsClicked}
837
+ onEscKey={this.onCloseComboMonths}
838
+ />
839
+ </ComboContainer>
840
+ );
841
+ }
842
+
843
+ renderComboYears() {
844
+ return (
845
+ <ComboContainer
846
+ show={this.showComboYears}
847
+ positionRef={this.nodeYears}
848
+ onClose={this.onCloseComboYears}
849
+ >
850
+ <FlatList
851
+ menuItemWidth="120px"
852
+ list={this.comboYearsList}
853
+ selectedId={this.props.visibleDate}
854
+ onChange={this.onComboYearsClicked}
855
+ onEscKey={this.onCloseComboYears}
856
+ />
857
+ </ComboContainer>
858
+ );
859
+ }
860
+
861
+ render() {
862
+ if (!this.props.visibleDate) {
863
+ return null;
864
+ }
865
+
866
+ return (
867
+ <div
868
+ className={
869
+ this.props.showTips
870
+ ? this.styles.classNames.calendarTips
871
+ : this.styles.classNames.calendar
872
+ }
873
+ onWheel={(e) => this.handleWheel(e)}
874
+ >
875
+ {this.renderMonths()}
876
+ {this.renderTips()}
877
+ {this.renderNavigator()}
878
+ {this.renderComboMonths()}
879
+ {this.renderComboYears()}
880
+ </div>
881
+ );
882
+ }
883
+ }
884
+
885
+ /******************************************************************************/
886
+
887
+ export default Widget.connect((state, props) => {
888
+ const userSession = Widget.getUserSession(state);
889
+ const data = userSession.get('tips.goblin-gadgets/calendar');
890
+ const tipsRank = data ? data.get('rank') : 0; // show first tip if state never defined
891
+
892
+ return {showTips: props.useTips && tipsRank !== -1};
893
+ })(Calendar);
894
+
895
+ registerWidget(Calendar, props, scenarios);