@ministryofjustice/frontend 4.0.1 → 5.0.0

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 (244) hide show
  1. package/govuk-prototype-kit.config.json +19 -4
  2. package/moj/_base.scss +2 -0
  3. package/moj/_base.scss.map +1 -0
  4. package/moj/all.bundle.js +2523 -0
  5. package/moj/all.bundle.js.map +1 -0
  6. package/moj/all.bundle.mjs +2502 -0
  7. package/moj/all.bundle.mjs.map +1 -0
  8. package/moj/all.mjs +59 -69
  9. package/moj/all.mjs.map +1 -1
  10. package/moj/all.scss +2 -0
  11. package/moj/all.scss.map +1 -0
  12. package/moj/components/_all.scss +2 -0
  13. package/moj/components/_all.scss.map +1 -0
  14. package/moj/components/action-bar/_action-bar.scss +2 -0
  15. package/moj/components/action-bar/_action-bar.scss.map +1 -0
  16. package/moj/components/add-another/_add-another.scss +2 -0
  17. package/moj/components/add-another/_add-another.scss.map +1 -0
  18. package/moj/components/add-another/add-another.bundle.js +128 -0
  19. package/moj/components/add-another/add-another.bundle.js.map +1 -0
  20. package/moj/components/add-another/add-another.bundle.mjs +120 -0
  21. package/moj/components/add-another/add-another.bundle.mjs.map +1 -0
  22. package/moj/components/add-another/add-another.mjs +112 -99
  23. package/moj/components/add-another/add-another.mjs.map +1 -1
  24. package/moj/components/alert/_alert.scss +4 -0
  25. package/moj/components/alert/_alert.scss.map +1 -0
  26. package/moj/components/alert/alert.bundle.js +330 -0
  27. package/moj/components/alert/alert.bundle.js.map +1 -0
  28. package/moj/components/alert/alert.bundle.mjs +322 -0
  29. package/moj/components/alert/alert.bundle.mjs.map +1 -0
  30. package/moj/components/alert/alert.mjs +181 -217
  31. package/moj/components/alert/alert.mjs.map +1 -1
  32. package/moj/components/alert/{alert.spec.helper.js → alert.spec.helper.bundle.js} +1 -1
  33. package/moj/components/alert/alert.spec.helper.bundle.js.map +1 -0
  34. package/moj/components/alert/alert.spec.helper.bundle.mjs +67 -0
  35. package/moj/components/alert/alert.spec.helper.bundle.mjs.map +1 -0
  36. package/moj/components/alert/alert.spec.helper.mjs.map +1 -1
  37. package/moj/components/badge/_badge.scss +2 -0
  38. package/moj/components/badge/_badge.scss.map +1 -0
  39. package/moj/components/banner/_banner.scss +2 -0
  40. package/moj/components/banner/_banner.scss.map +1 -0
  41. package/moj/components/button-menu/README.md +10 -6
  42. package/moj/components/button-menu/_button-menu.scss +4 -1
  43. package/moj/components/button-menu/_button-menu.scss.map +1 -0
  44. package/moj/components/button-menu/button-menu.bundle.js +299 -0
  45. package/moj/components/button-menu/button-menu.bundle.js.map +1 -0
  46. package/moj/components/button-menu/{button-menu.js → button-menu.bundle.mjs} +74 -121
  47. package/moj/components/button-menu/button-menu.bundle.mjs.map +1 -0
  48. package/moj/components/button-menu/button-menu.mjs +246 -285
  49. package/moj/components/button-menu/button-menu.mjs.map +1 -1
  50. package/moj/components/cookie-banner/_cookie-banner.scss +2 -0
  51. package/moj/components/cookie-banner/_cookie-banner.scss.map +1 -0
  52. package/moj/components/currency-input/_currency-input.scss +2 -0
  53. package/moj/components/currency-input/_currency-input.scss.map +1 -0
  54. package/moj/components/date-picker/_date-picker.scss +2 -0
  55. package/moj/components/date-picker/_date-picker.scss.map +1 -0
  56. package/moj/components/date-picker/date-picker.bundle.js +784 -0
  57. package/moj/components/date-picker/date-picker.bundle.js.map +1 -0
  58. package/moj/components/date-picker/{date-picker.js → date-picker.bundle.mjs} +245 -439
  59. package/moj/components/date-picker/date-picker.bundle.mjs.map +1 -0
  60. package/moj/components/date-picker/date-picker.mjs +654 -840
  61. package/moj/components/date-picker/date-picker.mjs.map +1 -1
  62. package/moj/components/filter/_filter.scss +2 -0
  63. package/moj/components/filter/_filter.scss.map +1 -0
  64. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js +96 -0
  65. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js.map +1 -0
  66. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs +88 -0
  67. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs.map +1 -0
  68. package/moj/components/filter-toggle-button/filter-toggle-button.mjs +78 -84
  69. package/moj/components/filter-toggle-button/filter-toggle-button.mjs.map +1 -1
  70. package/moj/components/form-validator/form-validator.bundle.js +198 -0
  71. package/moj/components/form-validator/form-validator.bundle.js.map +1 -0
  72. package/moj/components/form-validator/form-validator.bundle.mjs +190 -0
  73. package/moj/components/form-validator/form-validator.bundle.mjs.map +1 -0
  74. package/moj/components/form-validator/form-validator.mjs +149 -152
  75. package/moj/components/form-validator/form-validator.mjs.map +1 -1
  76. package/moj/components/header/_header.scss +2 -0
  77. package/moj/components/header/_header.scss.map +1 -0
  78. package/moj/components/identity-bar/_identity-bar.scss +2 -0
  79. package/moj/components/identity-bar/_identity-bar.scss.map +1 -0
  80. package/moj/components/interruption-card/_interruption-card.scss +2 -0
  81. package/moj/components/interruption-card/_interruption-card.scss.map +1 -0
  82. package/moj/components/messages/_messages.scss +2 -0
  83. package/moj/components/messages/_messages.scss.map +1 -0
  84. package/moj/components/multi-file-upload/_multi-file-upload.scss +2 -0
  85. package/moj/components/multi-file-upload/_multi-file-upload.scss.map +1 -0
  86. package/moj/components/multi-file-upload/multi-file-upload.bundle.js +223 -0
  87. package/moj/components/multi-file-upload/multi-file-upload.bundle.js.map +1 -0
  88. package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs +215 -0
  89. package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs.map +1 -0
  90. package/moj/components/multi-file-upload/multi-file-upload.mjs +193 -209
  91. package/moj/components/multi-file-upload/multi-file-upload.mjs.map +1 -1
  92. package/moj/components/multi-select/_multi-select.scss +2 -0
  93. package/moj/components/multi-select/_multi-select.scss.map +1 -0
  94. package/moj/components/multi-select/multi-select.bundle.js +78 -0
  95. package/moj/components/multi-select/multi-select.bundle.js.map +1 -0
  96. package/moj/components/multi-select/multi-select.bundle.mjs +70 -0
  97. package/moj/components/multi-select/multi-select.bundle.mjs.map +1 -0
  98. package/moj/components/multi-select/multi-select.mjs +59 -67
  99. package/moj/components/multi-select/multi-select.mjs.map +1 -1
  100. package/moj/components/notification-badge/_notification-badge.scss +2 -0
  101. package/moj/components/notification-badge/_notification-badge.scss.map +1 -0
  102. package/moj/components/organisation-switcher/_organisation-switcher.scss +2 -0
  103. package/moj/components/organisation-switcher/_organisation-switcher.scss.map +1 -0
  104. package/moj/components/page-header-actions/_page-header-actions.scss +2 -0
  105. package/moj/components/page-header-actions/_page-header-actions.scss.map +1 -0
  106. package/moj/components/pagination/_pagination.scss +2 -2
  107. package/moj/components/pagination/_pagination.scss.map +1 -0
  108. package/moj/components/password-reveal/_password-reveal.scss +2 -0
  109. package/moj/components/password-reveal/_password-reveal.scss.map +1 -0
  110. package/moj/components/password-reveal/password-reveal.bundle.js +49 -0
  111. package/moj/components/password-reveal/password-reveal.bundle.js.map +1 -0
  112. package/moj/components/password-reveal/password-reveal.bundle.mjs +41 -0
  113. package/moj/components/password-reveal/password-reveal.bundle.mjs.map +1 -0
  114. package/moj/components/password-reveal/password-reveal.mjs +36 -31
  115. package/moj/components/password-reveal/password-reveal.mjs.map +1 -1
  116. package/moj/components/primary-navigation/_primary-navigation.scss +2 -0
  117. package/moj/components/primary-navigation/_primary-navigation.scss.map +1 -0
  118. package/moj/components/progress-bar/_progress-bar.scss +2 -0
  119. package/moj/components/progress-bar/_progress-bar.scss.map +1 -0
  120. package/moj/components/rich-text-editor/README.md +15 -9
  121. package/moj/components/rich-text-editor/_rich-text-editor.scss +2 -0
  122. package/moj/components/rich-text-editor/_rich-text-editor.scss.map +1 -0
  123. package/moj/components/rich-text-editor/rich-text-editor.bundle.js +145 -0
  124. package/moj/components/rich-text-editor/rich-text-editor.bundle.js.map +1 -0
  125. package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs +137 -0
  126. package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs.map +1 -0
  127. package/moj/components/rich-text-editor/rich-text-editor.mjs +124 -145
  128. package/moj/components/rich-text-editor/rich-text-editor.mjs.map +1 -1
  129. package/moj/components/search/_search.scss +2 -0
  130. package/moj/components/search/_search.scss.map +1 -0
  131. package/moj/components/search-toggle/{search-toggle.scss → _search-toggle.scss} +2 -0
  132. package/moj/components/search-toggle/_search-toggle.scss.map +1 -0
  133. package/moj/components/search-toggle/search-toggle.bundle.js +54 -0
  134. package/moj/components/search-toggle/search-toggle.bundle.js.map +1 -0
  135. package/moj/components/search-toggle/search-toggle.bundle.mjs +46 -0
  136. package/moj/components/search-toggle/search-toggle.bundle.mjs.map +1 -0
  137. package/moj/components/search-toggle/search-toggle.mjs +40 -49
  138. package/moj/components/search-toggle/search-toggle.mjs.map +1 -1
  139. package/moj/components/side-navigation/_side-navigation.scss +2 -0
  140. package/moj/components/side-navigation/_side-navigation.scss.map +1 -0
  141. package/moj/components/sortable-table/_sortable-table.scss +2 -2
  142. package/moj/components/sortable-table/_sortable-table.scss.map +1 -0
  143. package/moj/components/sortable-table/sortable-table.bundle.js +134 -0
  144. package/moj/components/sortable-table/sortable-table.bundle.js.map +1 -0
  145. package/moj/components/sortable-table/sortable-table.bundle.mjs +126 -0
  146. package/moj/components/sortable-table/sortable-table.bundle.mjs.map +1 -0
  147. package/moj/components/sortable-table/sortable-table.mjs +117 -130
  148. package/moj/components/sortable-table/sortable-table.mjs.map +1 -1
  149. package/moj/components/sub-navigation/_sub-navigation.scss +2 -0
  150. package/moj/components/sub-navigation/_sub-navigation.scss.map +1 -0
  151. package/moj/components/tag/_tag.scss +2 -0
  152. package/moj/components/tag/_tag.scss.map +1 -0
  153. package/moj/components/task-list/_task-list.scss +2 -0
  154. package/moj/components/task-list/_task-list.scss.map +1 -0
  155. package/moj/components/ticket-panel/_ticket-panel.scss +2 -0
  156. package/moj/components/ticket-panel/_ticket-panel.scss.map +1 -0
  157. package/moj/components/timeline/_timeline.scss +2 -0
  158. package/moj/components/timeline/_timeline.scss.map +1 -0
  159. package/moj/filters/all.js +44 -22
  160. package/moj/helpers/_all.scss +2 -0
  161. package/moj/helpers/_all.scss.map +1 -0
  162. package/moj/helpers/_hidden.scss +2 -0
  163. package/moj/helpers/_hidden.scss.map +1 -0
  164. package/moj/helpers/_links.scss +2 -0
  165. package/moj/helpers/_links.scss.map +1 -0
  166. package/moj/{helpers.js → helpers.bundle.js} +37 -42
  167. package/moj/helpers.bundle.js.map +1 -0
  168. package/moj/helpers.bundle.mjs +179 -0
  169. package/moj/helpers.bundle.mjs.map +1 -0
  170. package/moj/helpers.mjs +52 -28
  171. package/moj/helpers.mjs.map +1 -1
  172. package/moj/init.js +11 -2
  173. package/moj/moj-frontend.min.css +1 -1
  174. package/moj/moj-frontend.min.css.map +1 -1
  175. package/moj/moj-frontend.min.js +1 -1
  176. package/moj/moj-frontend.min.js.map +1 -1
  177. package/moj/objects/_all.scss +2 -0
  178. package/moj/objects/_all.scss.map +1 -0
  179. package/moj/objects/_button-group.scss +2 -0
  180. package/moj/objects/_button-group.scss.map +1 -0
  181. package/moj/objects/_filter-layout.scss +2 -0
  182. package/moj/objects/_filter-layout.scss.map +1 -0
  183. package/moj/objects/_scrollable-pane.scss +2 -0
  184. package/moj/objects/_scrollable-pane.scss.map +1 -0
  185. package/moj/objects/_width-container.scss +2 -0
  186. package/moj/objects/_width-container.scss.map +1 -0
  187. package/moj/settings/_all.scss +2 -0
  188. package/moj/settings/_all.scss.map +1 -0
  189. package/moj/settings/_assets.scss +2 -0
  190. package/moj/settings/_assets.scss.map +1 -0
  191. package/moj/settings/_colours.scss +2 -0
  192. package/moj/settings/_colours.scss.map +1 -0
  193. package/moj/settings/_measurements.scss +2 -0
  194. package/moj/settings/_measurements.scss.map +1 -0
  195. package/moj/settings/_typography.scss +2 -0
  196. package/moj/settings/_typography.scss.map +1 -0
  197. package/moj/template.njk +13 -0
  198. package/moj/utilities/_all.scss +2 -0
  199. package/moj/utilities/_all.scss.map +1 -0
  200. package/moj/utilities/_hidden.scss +2 -0
  201. package/moj/utilities/_hidden.scss.map +1 -0
  202. package/moj/utilities/_width-container.scss +2 -0
  203. package/moj/utilities/_width-container.scss.map +1 -0
  204. package/moj/vendor/govuk-frontend/_base.scss +2 -0
  205. package/moj/vendor/govuk-frontend/_base.scss.map +1 -0
  206. package/moj/vendor/govuk-frontend/_index.scss +2 -0
  207. package/moj/vendor/govuk-frontend/_index.scss.map +1 -0
  208. package/moj/{version.js → version.bundle.js} +1 -1
  209. package/moj/version.bundle.js.map +1 -0
  210. package/moj/version.bundle.mjs +4 -0
  211. package/moj/version.bundle.mjs.map +1 -0
  212. package/moj/version.mjs.map +1 -1
  213. package/package.json +5 -6
  214. package/moj/all.jquery.min.js +0 -1
  215. package/moj/all.jquery.min.js.map +0 -1
  216. package/moj/all.js +0 -2662
  217. package/moj/all.js.map +0 -1
  218. package/moj/components/add-another/add-another.js +0 -115
  219. package/moj/components/add-another/add-another.js.map +0 -1
  220. package/moj/components/alert/alert.js +0 -356
  221. package/moj/components/alert/alert.js.map +0 -1
  222. package/moj/components/alert/alert.spec.helper.js.map +0 -1
  223. package/moj/components/button-menu/button-menu.js.map +0 -1
  224. package/moj/components/date-picker/date-picker.js.map +0 -1
  225. package/moj/components/filter-toggle-button/filter-toggle-button.js +0 -102
  226. package/moj/components/filter-toggle-button/filter-toggle-button.js.map +0 -1
  227. package/moj/components/form-validator/form-validator.js +0 -205
  228. package/moj/components/form-validator/form-validator.js.map +0 -1
  229. package/moj/components/multi-file-upload/multi-file-upload.js +0 -241
  230. package/moj/components/multi-file-upload/multi-file-upload.js.map +0 -1
  231. package/moj/components/multi-select/multi-select.js +0 -86
  232. package/moj/components/multi-select/multi-select.js.map +0 -1
  233. package/moj/components/password-reveal/password-reveal.js +0 -44
  234. package/moj/components/password-reveal/password-reveal.js.map +0 -1
  235. package/moj/components/rich-text-editor/rich-text-editor.js +0 -166
  236. package/moj/components/rich-text-editor/rich-text-editor.js.map +0 -1
  237. package/moj/components/search-toggle/search-toggle.js +0 -63
  238. package/moj/components/search-toggle/search-toggle.js.map +0 -1
  239. package/moj/components/sortable-table/sortable-table.js +0 -147
  240. package/moj/components/sortable-table/sortable-table.js.map +0 -1
  241. package/moj/helpers.js.map +0 -1
  242. package/moj/vendor/html5shiv.js +0 -326
  243. package/moj/vendor/jquery.js +0 -9300
  244. package/moj/version.js.map +0 -1
@@ -1,206 +1,123 @@
1
- (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.MOJFrontend = global.MOJFrontend || {}));
5
- })(this, (function (exports) { 'use strict';
6
-
7
- /**
8
- * Date picker config
9
- *
10
- * @typedef {object} DatePickerConfig
11
- * @property {string} [excludedDates] - Dates that cannot be selected
12
- * @property {string} [excludedDays] - Days that cannot be selected
13
- * @property {boolean} [leadingZeroes] - Whether to add leading zeroes when populating the field
14
- * @property {string} [minDate] - The earliest available date
15
- * @property {string} [maxDate] - The latest available date
16
- * @property {string} [weekStartDay] - First day of the week in calendar view
17
- */
18
-
1
+ class DatePicker {
19
2
  /**
20
- * @param {HTMLElement} $module - HTML element
21
- * @param {DatePickerConfig} config - config object
22
- * @class
3
+ * @param {Element | null} $module - HTML element to use for date picker
4
+ * @param {DatePickerConfig} [config] - Date picker config
23
5
  */
24
- function DatePicker($module, config = {}) {
25
- if (!$module) {
26
- return this
6
+ constructor($module, config = {}) {
7
+ if (!$module || !($module instanceof HTMLElement)) {
8
+ return this;
27
9
  }
10
+ const $input = $module.querySelector('.moj-js-datepicker-input');
28
11
 
12
+ // Check that required elements are present
13
+ if (!$input || !($input instanceof HTMLInputElement)) {
14
+ return this;
15
+ }
16
+ this.$module = $module;
17
+ this.$input = $input;
29
18
  const schema = Object.freeze({
30
19
  properties: {
31
- excludedDates: { type: 'string' },
32
- excludedDays: { type: 'string' },
33
- leadingZeros: { type: 'string' },
34
- maxDate: { type: 'string' },
35
- minDate: { type: 'string' },
36
- weekStartDay: { type: 'string' }
20
+ excludedDates: {
21
+ type: 'string'
22
+ },
23
+ excludedDays: {
24
+ type: 'string'
25
+ },
26
+ leadingZeros: {
27
+ type: 'string'
28
+ },
29
+ maxDate: {
30
+ type: 'string'
31
+ },
32
+ minDate: {
33
+ type: 'string'
34
+ },
35
+ weekStartDay: {
36
+ type: 'string'
37
+ }
37
38
  }
38
39
  });
39
-
40
40
  const defaults = {
41
41
  leadingZeros: false,
42
42
  weekStartDay: 'monday'
43
43
  };
44
44
 
45
45
  // data attributes override JS config, which overrides defaults
46
- this.config = this.mergeConfigs(
47
- defaults,
48
- config,
49
- this.parseDataset(schema, $module.dataset)
50
- );
51
-
52
- this.dayLabels = [
53
- 'Monday',
54
- 'Tuesday',
55
- 'Wednesday',
56
- 'Thursday',
57
- 'Friday',
58
- 'Saturday',
59
- 'Sunday'
60
- ];
61
-
62
- this.monthLabels = [
63
- 'January',
64
- 'February',
65
- 'March',
66
- 'April',
67
- 'May',
68
- 'June',
69
- 'July',
70
- 'August',
71
- 'September',
72
- 'October',
73
- 'November',
74
- 'December'
75
- ];
76
-
46
+ this.config = this.mergeConfigs(defaults, config, this.parseDataset(schema, $module.dataset));
47
+ this.dayLabels = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
48
+ this.monthLabels = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
77
49
  this.currentDate = new Date();
78
50
  this.currentDate.setHours(0, 0, 0, 0);
79
51
  this.calendarDays = [];
80
52
  this.excludedDates = [];
81
53
  this.excludedDays = [];
82
-
83
54
  this.buttonClass = 'moj-datepicker__button';
84
55
  this.selectedDayButtonClass = 'moj-datepicker__button--selected';
85
56
  this.currentDayButtonClass = 'moj-datepicker__button--current';
86
57
  this.todayButtonClass = 'moj-datepicker__button--today';
87
-
88
- this.$module = $module;
89
- this.$input = $module.querySelector('.moj-js-datepicker-input');
90
- }
91
-
92
- DatePicker.prototype.init = function () {
93
- // Check that required elements are present
94
- if (!this.$input) {
95
- return
96
- }
97
58
  if (this.$module.dataset.initialized) {
98
- return
59
+ return this;
99
60
  }
100
-
101
61
  this.setOptions();
102
62
  this.initControls();
103
63
  this.$module.setAttribute('data-initialized', 'true');
104
- };
105
-
106
- DatePicker.prototype.initControls = function () {
64
+ }
65
+ initControls() {
107
66
  this.id = `datepicker-${this.$input.id}`;
108
-
109
67
  this.$dialog = this.createDialog();
110
68
  this.createCalendarHeaders();
111
-
112
69
  const $componentWrapper = document.createElement('div');
113
70
  const $inputWrapper = document.createElement('div');
114
71
  $componentWrapper.classList.add('moj-datepicker__wrapper');
115
72
  $inputWrapper.classList.add('govuk-input__wrapper');
116
-
117
- this.$input.parentNode.insertBefore($componentWrapper, this.$input);
73
+ this.$input.parentElement.insertBefore($componentWrapper, this.$input);
118
74
  $componentWrapper.appendChild($inputWrapper);
119
75
  $inputWrapper.appendChild(this.$input);
120
-
121
76
  $inputWrapper.insertAdjacentHTML('beforeend', this.toggleTemplate());
122
77
  $componentWrapper.insertAdjacentElement('beforeend', this.$dialog);
123
-
124
78
  this.$calendarButton = this.$module.querySelector('.moj-js-datepicker-toggle');
125
- this.$dialogTitle = this.$dialog.querySelector(
126
- '.moj-js-datepicker-month-year'
127
- );
128
-
79
+ this.$dialogTitle = this.$dialog.querySelector('.moj-js-datepicker-month-year');
129
80
  this.createCalendar();
130
-
131
- this.$prevMonthButton = this.$dialog.querySelector(
132
- '.moj-js-datepicker-prev-month'
133
- );
134
- this.$prevYearButton = this.$dialog.querySelector(
135
- '.moj-js-datepicker-prev-year'
136
- );
137
- this.$nextMonthButton = this.$dialog.querySelector(
138
- '.moj-js-datepicker-next-month'
139
- );
140
- this.$nextYearButton = this.$dialog.querySelector(
141
- '.moj-js-datepicker-next-year'
142
- );
81
+ this.$prevMonthButton = this.$dialog.querySelector('.moj-js-datepicker-prev-month');
82
+ this.$prevYearButton = this.$dialog.querySelector('.moj-js-datepicker-prev-year');
83
+ this.$nextMonthButton = this.$dialog.querySelector('.moj-js-datepicker-next-month');
84
+ this.$nextYearButton = this.$dialog.querySelector('.moj-js-datepicker-next-year');
143
85
  this.$cancelButton = this.$dialog.querySelector('.moj-js-datepicker-cancel');
144
86
  this.$okButton = this.$dialog.querySelector('.moj-js-datepicker-ok');
145
87
 
146
88
  // add event listeners
147
- this.$prevMonthButton.addEventListener('click', (event) =>
148
- this.focusPreviousMonth(event, false)
149
- );
150
- this.$prevYearButton.addEventListener('click', (event) =>
151
- this.focusPreviousYear(event, false)
152
- );
153
- this.$nextMonthButton.addEventListener('click', (event) =>
154
- this.focusNextMonth(event, false)
155
- );
156
- this.$nextYearButton.addEventListener('click', (event) =>
157
- this.focusNextYear(event, false)
158
- );
159
- this.$cancelButton.addEventListener('click', (event) => {
89
+ this.$prevMonthButton.addEventListener('click', event => this.focusPreviousMonth(event, false));
90
+ this.$prevYearButton.addEventListener('click', event => this.focusPreviousYear(event, false));
91
+ this.$nextMonthButton.addEventListener('click', event => this.focusNextMonth(event, false));
92
+ this.$nextYearButton.addEventListener('click', event => this.focusNextYear(event, false));
93
+ this.$cancelButton.addEventListener('click', event => {
160
94
  event.preventDefault();
161
- this.closeDialog(event);
95
+ this.closeDialog();
162
96
  });
163
97
  this.$okButton.addEventListener('click', () => {
164
98
  this.selectDate(this.currentDate);
165
99
  });
166
-
167
- const dialogButtons = this.$dialog.querySelectorAll(
168
- 'button:not([disabled="true"])'
169
- );
170
- // eslint-disable-next-line prefer-destructuring
100
+ const dialogButtons = this.$dialog.querySelectorAll('button:not([disabled="true"])');
171
101
  this.$firstButtonInDialog = dialogButtons[0];
172
102
  this.$lastButtonInDialog = dialogButtons[dialogButtons.length - 1];
173
- this.$firstButtonInDialog.addEventListener('keydown', (event) =>
174
- this.firstButtonKeydown(event)
175
- );
176
- this.$lastButtonInDialog.addEventListener('keydown', (event) =>
177
- this.lastButtonKeydown(event)
178
- );
179
-
180
- this.$calendarButton.addEventListener('click', (event) =>
181
- this.toggleDialog(event)
182
- );
183
-
184
- this.$dialog.addEventListener('keydown', (event) => {
103
+ this.$firstButtonInDialog.addEventListener('keydown', event => this.firstButtonKeydown(event));
104
+ this.$lastButtonInDialog.addEventListener('keydown', event => this.lastButtonKeydown(event));
105
+ this.$calendarButton.addEventListener('click', event => this.toggleDialog(event));
106
+ this.$dialog.addEventListener('keydown', event => {
185
107
  if (event.key === 'Escape') {
186
108
  this.closeDialog();
187
109
  event.preventDefault();
188
110
  event.stopPropagation();
189
111
  }
190
112
  });
191
-
192
- document.body.addEventListener('mouseup', (event) =>
193
- this.backgroundClick(event)
194
- );
113
+ document.body.addEventListener('mouseup', event => this.backgroundClick(event));
195
114
 
196
115
  // populates calendar with initial dates, avoids Wave errors about null buttons
197
116
  this.updateCalendar();
198
- };
199
-
200
- DatePicker.prototype.createDialog = function () {
117
+ }
118
+ createDialog() {
201
119
  const titleId = `datepicker-title-${this.$input.id}`;
202
120
  const $dialog = document.createElement('div');
203
-
204
121
  $dialog.id = this.id;
205
122
  $dialog.setAttribute('class', 'moj-datepicker__dialog');
206
123
  $dialog.setAttribute('role', 'dialog');
@@ -208,34 +125,27 @@
208
125
  $dialog.setAttribute('aria-labelledby', titleId);
209
126
  $dialog.innerHTML = this.dialogTemplate(titleId);
210
127
  $dialog.hidden = true;
211
-
212
- return $dialog
213
- };
214
-
215
- DatePicker.prototype.createCalendar = function () {
128
+ return $dialog;
129
+ }
130
+ createCalendar() {
216
131
  const $tbody = this.$dialog.querySelector('tbody');
217
132
  let dayCount = 0;
218
133
  for (let i = 0; i < 6; i++) {
219
134
  // create row
220
135
  const $row = $tbody.insertRow(i);
221
-
222
136
  for (let j = 0; j < 7; j++) {
223
137
  // create cell (day)
224
138
  const $cell = document.createElement('td');
225
139
  const $dateButton = document.createElement('button');
226
-
227
140
  $cell.appendChild($dateButton);
228
141
  $row.appendChild($cell);
229
-
230
142
  const calendarDay = new DSCalendarDay($dateButton, dayCount, i, j, this);
231
- calendarDay.init();
232
143
  this.calendarDays.push(calendarDay);
233
144
  dayCount++;
234
145
  }
235
146
  }
236
- };
237
-
238
- DatePicker.prototype.toggleTemplate = function () {
147
+ }
148
+ toggleTemplate() {
239
149
  return `<button class="moj-datepicker__toggle moj-js-datepicker-toggle" type="button" aria-haspopup="dialog" aria-controls="${this.id}" aria-expanded="false">
240
150
  <span class="govuk-visually-hidden">Choose date</span>
241
151
  <svg width="32" height="24" focusable="false" class="moj-datepicker-icon" aria-hidden="true" role="img" viewBox="0 0 22 22">
@@ -248,8 +158,8 @@
248
158
  <rect x="3.66669" width="1.46667" height="5.13333" rx="0.733333" fill="currentColor"></rect>
249
159
  <rect x="16.8667" width="1.46667" height="5.13333" rx="0.733333" fill="currentColor"></rect>
250
160
  </svg>
251
- </button>`
252
- };
161
+ </button>`;
162
+ }
253
163
 
254
164
  /**
255
165
  * HTML template for calendar dialog
@@ -257,7 +167,7 @@
257
167
  * @param {string} [titleId] - Id attribute for dialog title
258
168
  * @returns {string}
259
169
  */
260
- DatePicker.prototype.dialogTemplate = function (titleId) {
170
+ dialogTemplate(titleId) {
261
171
  return `<div class="moj-datepicker__dialog-header">
262
172
  <div class="moj-datepicker__dialog-navbuttons">
263
173
  <button class="moj-datepicker__button moj-js-datepicker-prev-year">
@@ -307,16 +217,15 @@
307
217
  <div class="govuk-button-group">
308
218
  <button type="button" class="govuk-button moj-js-datepicker-ok">Select</button>
309
219
  <button type="button" class="govuk-button govuk-button--secondary moj-js-datepicker-cancel">Close</button>
310
- </div>`
311
- };
312
-
313
- DatePicker.prototype.createCalendarHeaders = function () {
314
- this.dayLabels.forEach((day) => {
220
+ </div>`;
221
+ }
222
+ createCalendarHeaders() {
223
+ this.dayLabels.forEach(day => {
315
224
  const html = `<th scope="col"><span aria-hidden="true">${day.substring(0, 3)}</span><span class="govuk-visually-hidden">${day}</span></th>`;
316
225
  const $headerRow = this.$dialog.querySelector('thead > tr');
317
226
  $headerRow.insertAdjacentHTML('beforeend', html);
318
227
  });
319
- };
228
+ }
320
229
 
321
230
  /**
322
231
  * Pads given number with leading zeros
@@ -325,66 +234,50 @@
325
234
  * @param {number} length - The length in characters of the output
326
235
  * @returns {string}
327
236
  */
328
- DatePicker.prototype.leadingZeros = function (value, length = 2) {
237
+ leadingZeros(value, length = 2) {
329
238
  let ret = value.toString();
330
-
331
239
  while (ret.length < length) {
332
240
  ret = `0${ret}`;
333
241
  }
334
-
335
- return ret
336
- };
337
-
338
- DatePicker.prototype.setOptions = function () {
242
+ return ret;
243
+ }
244
+ setOptions() {
339
245
  this.setMinAndMaxDatesOnCalendar();
340
246
  this.setExcludedDates();
341
247
  this.setExcludedDays();
342
248
  this.setLeadingZeros();
343
249
  this.setWeekStartDay();
344
- };
345
-
346
- DatePicker.prototype.setMinAndMaxDatesOnCalendar = function () {
250
+ }
251
+ setMinAndMaxDatesOnCalendar() {
347
252
  if (this.config.minDate) {
348
253
  this.minDate = this.formattedDateFromString(this.config.minDate, null);
349
254
  if (this.minDate && this.currentDate < this.minDate) {
350
255
  this.currentDate = this.minDate;
351
256
  }
352
257
  }
353
-
354
258
  if (this.config.maxDate) {
355
259
  this.maxDate = this.formattedDateFromString(this.config.maxDate, null);
356
260
  if (this.maxDate && this.currentDate > this.maxDate) {
357
261
  this.currentDate = this.maxDate;
358
262
  }
359
263
  }
360
- };
361
-
362
- DatePicker.prototype.setExcludedDates = function () {
264
+ }
265
+ setExcludedDates() {
363
266
  if (this.config.excludedDates) {
364
- this.excludedDates = this.config.excludedDates
365
- .replace(/\s+/, ' ')
366
- .split(' ')
367
- .map((item) => {
368
- return item.includes('-')
369
- ? this.parseDateRangeString(item)
370
- : this.formattedDateFromString(item)
371
- })
372
- .flat()
373
- .filter((item) => item);
374
- }
375
- };
267
+ this.excludedDates = this.config.excludedDates.replace(/\s+/, ' ').split(' ').map(item => {
268
+ return item.includes('-') ? this.parseDateRangeString(item) : [this.formattedDateFromString(item)];
269
+ }).reduce((dates, items) => dates.concat(items)).filter(date => date);
270
+ }
271
+ }
376
272
 
377
273
  /*
378
274
  * Parses a daterange string into an array of dates
379
275
  * @param {String} datestring - A daterange string in the format "dd/mm/yyyy-dd/mm/yyyy"
380
276
  * @returns {Date[]}
381
277
  */
382
- DatePicker.prototype.parseDateRangeString = function (datestring) {
278
+ parseDateRangeString(datestring) {
383
279
  const dates = [];
384
- const [startDate, endDate] = datestring
385
- .split('-')
386
- .map((d) => this.formattedDateFromString(d, null));
387
-
280
+ const [startDate, endDate] = datestring.split('-').map(d => this.formattedDateFromString(d, null));
388
281
  if (startDate && endDate) {
389
282
  const date = new Date(startDate.getTime());
390
283
  /* eslint-disable no-unmodified-loop-condition */
@@ -394,40 +287,31 @@
394
287
  }
395
288
  /* eslint-enable no-unmodified-loop-condition */
396
289
  }
397
- return dates
398
- };
399
-
400
- DatePicker.prototype.setExcludedDays = function () {
290
+ return dates;
291
+ }
292
+ setExcludedDays() {
401
293
  if (this.config.excludedDays) {
402
294
  // lowercase and arrange dayLabels to put indexOf sunday == 0 for comparison
403
295
  // with getDay() function
404
- const weekDays = this.dayLabels.map((item) => item.toLowerCase());
296
+ const weekDays = this.dayLabels.map(item => item.toLowerCase());
405
297
  if (this.config.weekStartDay === 'monday') {
406
298
  weekDays.unshift(weekDays.pop());
407
299
  }
408
-
409
- this.excludedDays = this.config.excludedDays
410
- .replace(/\s+/, ' ')
411
- .toLowerCase()
412
- .split(' ')
413
- .map((item) => weekDays.indexOf(item))
414
- .filter((item) => item !== -1);
300
+ this.excludedDays = this.config.excludedDays.replace(/\s+/, ' ').toLowerCase().split(' ').map(item => weekDays.indexOf(item)).filter(item => item !== -1);
415
301
  }
416
- };
417
-
418
- DatePicker.prototype.setLeadingZeros = function () {
302
+ }
303
+ setLeadingZeros() {
419
304
  if (typeof this.config.leadingZeros !== 'boolean') {
420
305
  if (this.config.leadingZeros.toLowerCase() === 'true') {
421
306
  this.config.leadingZeros = true;
422
- return
307
+ return;
423
308
  }
424
309
  if (this.config.leadingZeros.toLowerCase() === 'false') {
425
310
  this.config.leadingZeros = false;
426
311
  }
427
312
  }
428
- };
429
-
430
- DatePicker.prototype.setWeekStartDay = function () {
313
+ }
314
+ setWeekStartDay() {
431
315
  const weekStartDayParam = this.config.weekStartDay;
432
316
  if (weekStartDayParam && weekStartDayParam.toLowerCase() === 'sunday') {
433
317
  this.config.weekStartDay = 'sunday';
@@ -436,7 +320,7 @@
436
320
  } else {
437
321
  this.config.weekStartDay = 'monday';
438
322
  }
439
- };
323
+ }
440
324
 
441
325
  /**
442
326
  * Determine if a date is selecteable
@@ -444,30 +328,27 @@
444
328
  * @param {Date} date - the date to check
445
329
  * @returns {boolean}
446
330
  */
447
- DatePicker.prototype.isExcludedDate = function (date) {
331
+ isExcludedDate(date) {
448
332
  // This comparison does not work correctly - it will exclude the mindate itself
449
333
  // see: https://github.com/ministryofjustice/moj-frontend/issues/923
450
334
  if (this.minDate && this.minDate > date) {
451
- return true
335
+ return true;
452
336
  }
453
337
 
454
338
  // This comparison works as expected - the maxdate will not be excluded
455
339
  if (this.maxDate && this.maxDate < date) {
456
- return true
340
+ return true;
457
341
  }
458
-
459
342
  for (const excludedDate of this.excludedDates) {
460
343
  if (date.toDateString() === excludedDate.toDateString()) {
461
- return true
344
+ return true;
462
345
  }
463
346
  }
464
-
465
347
  if (this.excludedDays.includes(date.getDay())) {
466
- return true
348
+ return true;
467
349
  }
468
-
469
- return false
470
- };
350
+ return false;
351
+ }
471
352
 
472
353
  /**
473
354
  * Get a Date object from a string
@@ -476,27 +357,21 @@
476
357
  * @param {Date} fallback - date object to return if formatting fails
477
358
  * @returns {Date}
478
359
  */
479
- DatePicker.prototype.formattedDateFromString = function (
480
- dateString,
481
- fallback = new Date()
482
- ) {
360
+ formattedDateFromString(dateString, fallback = new Date()) {
483
361
  let formattedDate = null;
484
362
  // Accepts d/m/yyyy and dd/mm/yyyy
485
363
  const dateFormatPattern = /(\d{1,2})([-/,. ])(\d{1,2})\2(\d{4})/;
486
-
487
- if (!dateFormatPattern.test(dateString)) return fallback
488
-
489
- const match = dateString.match(dateFormatPattern);
364
+ if (!dateFormatPattern.test(dateString)) return fallback;
365
+ const match = dateFormatPattern.exec(dateString);
490
366
  const day = match[1];
491
367
  const month = match[3];
492
368
  const year = match[4];
493
-
494
369
  formattedDate = new Date(`${year}-${month}-${day}`);
495
- if (formattedDate instanceof Date && !isNaN(formattedDate)) {
496
- return formattedDate
370
+ if (formattedDate instanceof Date && Number.isFinite(formattedDate.getTime())) {
371
+ return formattedDate;
497
372
  }
498
- return fallback
499
- };
373
+ return fallback;
374
+ }
500
375
 
501
376
  /**
502
377
  * Get a formatted date string from a Date object
@@ -504,13 +379,12 @@
504
379
  * @param {Date} date - date to format to a string
505
380
  * @returns {string}
506
381
  */
507
- DatePicker.prototype.formattedDateFromDate = function (date) {
382
+ formattedDateFromDate(date) {
508
383
  if (this.config.leadingZeros) {
509
- return `${this.leadingZeros(date.getDate())}/${this.leadingZeros(date.getMonth() + 1)}/${date.getFullYear()}`
384
+ return `${this.leadingZeros(date.getDate())}/${this.leadingZeros(date.getMonth() + 1)}/${date.getFullYear()}`;
510
385
  }
511
-
512
- return `${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`
513
- };
386
+ return `${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`;
387
+ }
514
388
 
515
389
  /**
516
390
  * Get a human readable date in the format Monday 2 March 2024
@@ -518,100 +392,77 @@
518
392
  * @param {Date} date - date to format
519
393
  * @returns {string}
520
394
  */
521
- DatePicker.prototype.formattedDateHuman = function (date) {
522
- return `${this.dayLabels[(date.getDay() + 6) % 7]} ${date.getDate()} ${this.monthLabels[date.getMonth()]} ${date.getFullYear()}`
523
- };
524
-
525
- DatePicker.prototype.backgroundClick = function (event) {
526
- if (
527
- this.isOpen() &&
528
- !this.$dialog.contains(event.target) &&
529
- !this.$input.contains(event.target) &&
530
- !this.$calendarButton.contains(event.target)
531
- ) {
395
+ formattedDateHuman(date) {
396
+ return `${this.dayLabels[(date.getDay() + 6) % 7]} ${date.getDate()} ${this.monthLabels[date.getMonth()]} ${date.getFullYear()}`;
397
+ }
398
+ backgroundClick(event) {
399
+ if (this.isOpen() && event.target instanceof Node && !this.$dialog.contains(event.target) && !this.$input.contains(event.target) && !this.$calendarButton.contains(event.target)) {
532
400
  event.preventDefault();
533
401
  this.closeDialog();
534
402
  }
535
- };
536
-
537
- DatePicker.prototype.firstButtonKeydown = function (event) {
403
+ }
404
+ firstButtonKeydown(event) {
538
405
  if (event.key === 'Tab' && event.shiftKey) {
539
406
  this.$lastButtonInDialog.focus();
540
407
  event.preventDefault();
541
408
  }
542
- };
543
-
544
- DatePicker.prototype.lastButtonKeydown = function (event) {
409
+ }
410
+ lastButtonKeydown(event) {
545
411
  if (event.key === 'Tab' && !event.shiftKey) {
546
412
  this.$firstButtonInDialog.focus();
547
413
  event.preventDefault();
548
414
  }
549
- };
415
+ }
550
416
 
551
417
  // render calendar
552
- DatePicker.prototype.updateCalendar = function () {
418
+ updateCalendar() {
553
419
  this.$dialogTitle.innerHTML = `${this.monthLabels[this.currentDate.getMonth()]} ${this.currentDate.getFullYear()}`;
554
-
555
420
  const day = this.currentDate;
556
421
  const firstOfMonth = new Date(day.getFullYear(), day.getMonth(), 1);
557
422
  let dayOfWeek;
558
-
559
423
  if (this.config.weekStartDay === 'monday') {
560
424
  dayOfWeek = firstOfMonth.getDay() === 0 ? 6 : firstOfMonth.getDay() - 1; // Change logic to make Monday first day of week, i.e. 0
561
425
  } else {
562
426
  dayOfWeek = firstOfMonth.getDay();
563
427
  }
564
-
565
428
  firstOfMonth.setDate(firstOfMonth.getDate() - dayOfWeek);
566
-
567
429
  const thisDay = new Date(firstOfMonth);
568
430
 
569
431
  // loop through our days
570
- for (let i = 0; i < this.calendarDays.length; i++) {
432
+ for (const calendarDay of this.calendarDays) {
571
433
  const hidden = thisDay.getMonth() !== day.getMonth();
572
434
  const disabled = this.isExcludedDate(thisDay);
573
-
574
- this.calendarDays[i].update(thisDay, hidden, disabled);
575
-
435
+ calendarDay.update(thisDay, hidden, disabled);
576
436
  thisDay.setDate(thisDay.getDate() + 1);
577
437
  }
578
- };
579
-
580
- DatePicker.prototype.setCurrentDate = function (focus = true) {
581
- const { currentDate } = this;
582
- this.calendarDays.forEach((calendarDay) => {
438
+ }
439
+ setCurrentDate(focus = true) {
440
+ const {
441
+ currentDate
442
+ } = this;
443
+ this.calendarDays.forEach(calendarDay => {
583
444
  calendarDay.button.classList.add('moj-datepicker__button');
584
445
  calendarDay.button.classList.add('moj-datepicker__calendar-day');
585
- calendarDay.button.setAttribute('tabindex', -1);
446
+ calendarDay.button.setAttribute('tabindex', '-1');
586
447
  calendarDay.button.classList.remove(this.selectedDayButtonClass);
587
448
  const calendarDayDate = calendarDay.date;
588
449
  calendarDayDate.setHours(0, 0, 0, 0);
589
-
590
450
  const today = new Date();
591
451
  today.setHours(0, 0, 0, 0);
592
-
593
- if (
594
- calendarDayDate.getTime() ===
595
- currentDate.getTime() /* && !calendarDay.button.disabled */
596
- ) {
452
+ if (calendarDayDate.getTime() === currentDate.getTime() /* && !calendarDay.button.disabled */) {
597
453
  if (focus) {
598
- calendarDay.button.setAttribute('tabindex', 0);
454
+ calendarDay.button.setAttribute('tabindex', '0');
599
455
  calendarDay.button.focus();
600
456
  calendarDay.button.classList.add(this.selectedDayButtonClass);
601
457
  }
602
458
  }
603
-
604
- if (
605
- this.inputDate &&
606
- calendarDayDate.getTime() === this.inputDate.getTime()
607
- ) {
459
+ if (this.inputDate && calendarDayDate.getTime() === this.inputDate.getTime()) {
608
460
  calendarDay.button.classList.add(this.currentDayButtonClass);
609
461
  calendarDay.button.setAttribute('aria-current', 'date');
610
462
  } else {
611
463
  calendarDay.button.classList.remove(this.currentDayButtonClass);
612
464
  calendarDay.button.removeAttribute('aria-current');
613
465
  }
614
-
615
466
  if (calendarDayDate.getTime() === today.getTime()) {
616
467
  calendarDay.button.classList.add(this.todayButtonClass);
617
468
  } else {
@@ -621,39 +472,30 @@
621
472
 
622
473
  // if no date is tab-able, make the first non-disabled date tab-able
623
474
  if (!focus) {
624
- const enabledDays = this.calendarDays.filter((calendarDay) => {
625
- return (
626
- window.getComputedStyle(calendarDay.button).display === 'block' &&
627
- !calendarDay.button.disabled
628
- )
475
+ const enabledDays = this.calendarDays.filter(calendarDay => {
476
+ return window.getComputedStyle(calendarDay.button).display === 'block' && !calendarDay.button.disabled;
629
477
  });
630
-
631
- enabledDays[0].button.setAttribute('tabindex', 0);
632
-
478
+ enabledDays[0].button.setAttribute('tabindex', '0');
633
479
  this.currentDate = enabledDays[0].date;
634
480
  }
635
- };
636
-
637
- DatePicker.prototype.selectDate = function (date) {
481
+ }
482
+ selectDate(date) {
638
483
  if (this.isExcludedDate(date)) {
639
- return
484
+ return;
640
485
  }
641
-
642
- this.$calendarButton.querySelector('span').innerText =
643
- `Choose date. Selected date is ${this.formattedDateHuman(date)}`;
486
+ this.$calendarButton.querySelector('span').innerText = `Choose date. Selected date is ${this.formattedDateHuman(date)}`;
644
487
  this.$input.value = this.formattedDateFromDate(date);
645
-
646
- const changeEvent = new Event('change', { bubbles: true, cancelable: true });
488
+ const changeEvent = new Event('change', {
489
+ bubbles: true,
490
+ cancelable: true
491
+ });
647
492
  this.$input.dispatchEvent(changeEvent);
648
-
649
493
  this.closeDialog();
650
- };
651
-
652
- DatePicker.prototype.isOpen = function () {
653
- return this.$dialog.classList.contains('moj-datepicker__dialog--open')
654
- };
655
-
656
- DatePicker.prototype.toggleDialog = function (event) {
494
+ }
495
+ isOpen() {
496
+ return this.$dialog.classList.contains('moj-datepicker__dialog--open');
497
+ }
498
+ toggleDialog(event) {
657
499
  event.preventDefault();
658
500
  if (this.isOpen()) {
659
501
  this.closeDialog();
@@ -661,9 +503,8 @@
661
503
  this.setMinAndMaxDatesOnCalendar();
662
504
  this.openDialog();
663
505
  }
664
- };
665
-
666
- DatePicker.prototype.openDialog = function () {
506
+ }
507
+ openDialog() {
667
508
  this.$dialog.hidden = false;
668
509
  this.$dialog.classList.add('moj-datepicker__dialog--open');
669
510
  this.$calendarButton.setAttribute('aria-expanded', 'true');
@@ -679,117 +520,93 @@
679
520
  this.inputDate = this.formattedDateFromString(this.$input.value);
680
521
  this.currentDate = this.inputDate;
681
522
  this.currentDate.setHours(0, 0, 0, 0);
682
-
683
523
  this.updateCalendar();
684
524
  this.setCurrentDate();
685
- };
686
-
687
- DatePicker.prototype.closeDialog = function () {
525
+ }
526
+ closeDialog() {
688
527
  this.$dialog.hidden = true;
689
528
  this.$dialog.classList.remove('moj-datepicker__dialog--open');
690
529
  this.$calendarButton.setAttribute('aria-expanded', 'false');
691
530
  this.$calendarButton.focus();
692
- };
693
-
694
- DatePicker.prototype.goToDate = function (date, focus) {
531
+ }
532
+ goToDate(date, focus) {
695
533
  const current = this.currentDate;
696
534
  this.currentDate = date;
697
-
698
- if (
699
- current.getMonth() !== this.currentDate.getMonth() ||
700
- current.getFullYear() !== this.currentDate.getFullYear()
701
- ) {
535
+ if (current.getMonth() !== this.currentDate.getMonth() || current.getFullYear() !== this.currentDate.getFullYear()) {
702
536
  this.updateCalendar();
703
537
  }
704
-
705
538
  this.setCurrentDate(focus);
706
- };
539
+ }
707
540
 
708
541
  // day navigation
709
- DatePicker.prototype.focusNextDay = function () {
542
+ focusNextDay() {
710
543
  const date = new Date(this.currentDate);
711
544
  date.setDate(date.getDate() + 1);
712
545
  this.goToDate(date);
713
- };
714
-
715
- DatePicker.prototype.focusPreviousDay = function () {
546
+ }
547
+ focusPreviousDay() {
716
548
  const date = new Date(this.currentDate);
717
549
  date.setDate(date.getDate() - 1);
718
550
  this.goToDate(date);
719
- };
551
+ }
720
552
 
721
553
  // week navigation
722
- DatePicker.prototype.focusNextWeek = function () {
554
+ focusNextWeek() {
723
555
  const date = new Date(this.currentDate);
724
556
  date.setDate(date.getDate() + 7);
725
557
  this.goToDate(date);
726
- };
727
-
728
- DatePicker.prototype.focusPreviousWeek = function () {
558
+ }
559
+ focusPreviousWeek() {
729
560
  const date = new Date(this.currentDate);
730
561
  date.setDate(date.getDate() - 7);
731
562
  this.goToDate(date);
732
- };
733
-
734
- DatePicker.prototype.focusFirstDayOfWeek = function () {
563
+ }
564
+ focusFirstDayOfWeek() {
735
565
  const date = new Date(this.currentDate);
736
566
  const firstDayOfWeekIndex = this.config.weekStartDay === 'sunday' ? 0 : 1;
737
567
  const dayOfWeek = date.getDay();
738
- const diff =
739
- dayOfWeek >= firstDayOfWeekIndex
740
- ? dayOfWeek - firstDayOfWeekIndex
741
- : 6 - dayOfWeek;
742
-
568
+ const diff = dayOfWeek >= firstDayOfWeekIndex ? dayOfWeek - firstDayOfWeekIndex : 6 - dayOfWeek;
743
569
  date.setDate(date.getDate() - diff);
744
570
  date.setHours(0, 0, 0, 0);
745
-
746
571
  this.goToDate(date);
747
- };
748
-
749
- DatePicker.prototype.focusLastDayOfWeek = function () {
572
+ }
573
+ focusLastDayOfWeek() {
750
574
  const date = new Date(this.currentDate);
751
575
  const lastDayOfWeekIndex = this.config.weekStartDay === 'sunday' ? 6 : 0;
752
576
  const dayOfWeek = date.getDay();
753
- const diff =
754
- dayOfWeek <= lastDayOfWeekIndex
755
- ? lastDayOfWeekIndex - dayOfWeek
756
- : 7 - dayOfWeek;
757
-
577
+ const diff = dayOfWeek <= lastDayOfWeekIndex ? lastDayOfWeekIndex - dayOfWeek : 7 - dayOfWeek;
758
578
  date.setDate(date.getDate() + diff);
759
579
  date.setHours(0, 0, 0, 0);
760
-
761
580
  this.goToDate(date);
762
- };
581
+ }
763
582
 
764
583
  // month navigation
765
- DatePicker.prototype.focusNextMonth = function (event, focus = true) {
584
+ focusNextMonth(event, focus = true) {
766
585
  event.preventDefault();
767
586
  const date = new Date(this.currentDate);
768
587
  date.setMonth(date.getMonth() + 1, 1);
769
588
  this.goToDate(date, focus);
770
- };
771
-
772
- DatePicker.prototype.focusPreviousMonth = function (event, focus = true) {
589
+ }
590
+ focusPreviousMonth(event, focus = true) {
773
591
  event.preventDefault();
774
592
  const date = new Date(this.currentDate);
775
593
  date.setMonth(date.getMonth() - 1, 1);
776
594
  this.goToDate(date, focus);
777
- };
595
+ }
778
596
 
779
597
  // year navigation
780
- DatePicker.prototype.focusNextYear = function (event, focus = true) {
598
+ focusNextYear(event, focus = true) {
781
599
  event.preventDefault();
782
600
  const date = new Date(this.currentDate);
783
601
  date.setFullYear(date.getFullYear() + 1, date.getMonth(), 1);
784
602
  this.goToDate(date, focus);
785
- };
786
-
787
- DatePicker.prototype.focusPreviousYear = function (event, focus = true) {
603
+ }
604
+ focusPreviousYear(event, focus = true) {
788
605
  event.preventDefault();
789
606
  const date = new Date(this.currentDate);
790
607
  date.setFullYear(date.getFullYear() - 1, date.getMonth(), 1);
791
608
  this.goToDate(date, focus);
792
- };
609
+ }
793
610
 
794
611
  /**
795
612
  * Parse dataset
@@ -798,17 +615,15 @@
798
615
  * @param {DOMStringMap} dataset - HTML element dataset
799
616
  * @returns {object} Normalised dataset
800
617
  */
801
- DatePicker.prototype.parseDataset = function (schema, dataset) {
618
+ parseDataset(schema, dataset) {
802
619
  const parsed = {};
803
-
804
- for (const [field, ,] of Object.entries(schema.properties)) {
620
+ for (const [field,,] of Object.entries(schema.properties)) {
805
621
  if (field in dataset) {
806
622
  parsed[field] = dataset[field];
807
623
  }
808
624
  }
809
-
810
- return parsed
811
- };
625
+ return parsed;
626
+ }
812
627
 
813
628
  /**
814
629
  * Config merging function
@@ -819,7 +634,7 @@
819
634
  * @param {...{ [key: string]: unknown }} configObjects - Config objects to merge
820
635
  * @returns {{ [key: string]: unknown }} A merged config object
821
636
  */
822
- DatePicker.prototype.mergeConfigs = function (...configObjects) {
637
+ mergeConfigs(...configObjects) {
823
638
  const formattedConfigObject = {};
824
639
 
825
640
  // Loop through each of the passed objects
@@ -839,10 +654,10 @@
839
654
  }
840
655
  }
841
656
  }
842
-
843
- return formattedConfigObject
844
- };
845
-
657
+ return formattedConfigObject;
658
+ }
659
+ }
660
+ class DSCalendarDay {
846
661
  /**
847
662
  *
848
663
  * @param {HTMLElement} button
@@ -850,121 +665,112 @@
850
665
  * @param {number} row
851
666
  * @param {number} column
852
667
  * @param {DatePicker} picker
853
- * @class
854
668
  */
855
- function DSCalendarDay(button, index, row, column, picker) {
669
+ constructor(button, index, row, column, picker) {
856
670
  this.index = index;
857
671
  this.row = row;
858
672
  this.column = column;
859
673
  this.button = button;
860
674
  this.picker = picker;
861
-
862
675
  this.date = new Date();
863
- }
864
-
865
- DSCalendarDay.prototype.init = function () {
866
676
  this.button.addEventListener('keydown', this.keyPress.bind(this));
867
677
  this.button.addEventListener('click', this.click.bind(this));
868
- };
678
+ }
869
679
 
870
680
  /**
871
681
  * @param {Date} day - the Date for the calendar day
872
682
  * @param {boolean} hidden - visibility of the day
873
683
  * @param {boolean} disabled - is the day selectable or excluded
874
684
  */
875
- DSCalendarDay.prototype.update = function (day, hidden, disabled) {
685
+ update(day, hidden, disabled) {
876
686
  const label = day.getDate();
877
687
  let accessibleLabel = this.picker.formattedDateHuman(day);
878
-
879
688
  if (disabled) {
880
- this.button.setAttribute('aria-disabled', true);
689
+ this.button.setAttribute('aria-disabled', 'true');
881
690
  accessibleLabel = `Excluded date, ${accessibleLabel}`;
882
691
  } else {
883
692
  this.button.removeAttribute('aria-disabled');
884
693
  }
885
-
886
694
  if (hidden) {
887
695
  this.button.style.display = 'none';
888
696
  } else {
889
697
  this.button.style.display = 'block';
890
698
  }
891
- this.button.setAttribute(
892
- 'data-testid',
893
- this.picker.formattedDateFromDate(day)
894
- );
895
-
699
+ this.button.setAttribute('data-testid', this.picker.formattedDateFromDate(day));
896
700
  this.button.innerHTML = `<span class="govuk-visually-hidden">${accessibleLabel}</span><span aria-hidden="true">${label}</span>`;
897
701
  this.date = new Date(day);
898
- };
899
-
900
- DSCalendarDay.prototype.click = function (event) {
702
+ }
703
+ click(event) {
901
704
  this.picker.goToDate(this.date);
902
705
  this.picker.selectDate(this.date);
903
-
904
706
  event.stopPropagation();
905
707
  event.preventDefault();
906
- };
907
-
908
- DSCalendarDay.prototype.keyPress = function (event) {
708
+ }
709
+ keyPress(event) {
909
710
  let calendarNavKey = true;
910
-
911
711
  switch (event.key) {
912
712
  case 'ArrowLeft':
913
713
  this.picker.focusPreviousDay();
914
- break
714
+ break;
915
715
  case 'ArrowRight':
916
716
  this.picker.focusNextDay();
917
- break
717
+ break;
918
718
  case 'ArrowUp':
919
719
  this.picker.focusPreviousWeek();
920
- break
720
+ break;
921
721
  case 'ArrowDown':
922
722
  this.picker.focusNextWeek();
923
- break
723
+ break;
924
724
  case 'Home':
925
725
  this.picker.focusFirstDayOfWeek();
926
- break
726
+ break;
927
727
  case 'End':
928
728
  this.picker.focusLastDayOfWeek();
929
- break
729
+ break;
930
730
  case 'PageUp':
931
- // eslint-disable-next-line no-unused-expressions
932
- event.shiftKey
933
- ? this.picker.focusPreviousYear(event)
934
- : this.picker.focusPreviousMonth(event);
935
- break
731
+ {
732
+ if (event.shiftKey) {
733
+ this.picker.focusPreviousYear(event);
734
+ } else {
735
+ this.picker.focusPreviousMonth(event);
736
+ }
737
+ break;
738
+ }
936
739
  case 'PageDown':
937
- // eslint-disable-next-line no-unused-expressions
938
- event.shiftKey
939
- ? this.picker.focusNextYear(event)
940
- : this.picker.focusNextMonth(event);
941
- break
740
+ {
741
+ if (event.shiftKey) {
742
+ this.picker.focusNextYear(event);
743
+ } else {
744
+ this.picker.focusNextMonth(event);
745
+ }
746
+ break;
747
+ }
942
748
  default:
943
749
  calendarNavKey = false;
944
- break
750
+ break;
945
751
  }
946
-
947
752
  if (calendarNavKey) {
948
753
  event.preventDefault();
949
754
  event.stopPropagation();
950
755
  }
951
- };
952
-
953
- /**
954
- * Schema for component config
955
- *
956
- * @typedef {object} Schema
957
- * @property {{ [field: string]: SchemaProperty | undefined }} properties - Schema properties
958
- */
959
-
960
- /**
961
- * Schema property for component config
962
- *
963
- * @typedef {object} SchemaProperty
964
- * @property {'string' | 'boolean' | 'number' | 'object'} type - Property type
965
- */
966
-
967
- exports.DatePicker = DatePicker;
968
-
969
- }));
970
- //# sourceMappingURL=date-picker.js.map
756
+ }
757
+ }
758
+
759
+ /**
760
+ * Date picker config
761
+ *
762
+ * @typedef {object} DatePickerConfig
763
+ * @property {string} [excludedDates] - Dates that cannot be selected
764
+ * @property {string} [excludedDays] - Days that cannot be selected
765
+ * @property {boolean} [leadingZeroes] - Whether to add leading zeroes when populating the field
766
+ * @property {string} [minDate] - The earliest available date
767
+ * @property {string} [maxDate] - The latest available date
768
+ * @property {string} [weekStartDay] - First day of the week in calendar view
769
+ */
770
+
771
+ /**
772
+ * @import { Schema } from '../../all.mjs'
773
+ */
774
+
775
+ export { DatePicker };
776
+ //# sourceMappingURL=date-picker.bundle.mjs.map