@ministryofjustice/frontend 4.0.1 → 5.1.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 (256) 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 +3010 -0
  5. package/moj/all.bundle.js.map +1 -0
  6. package/moj/all.bundle.mjs +3293 -0
  7. package/moj/all.bundle.mjs.map +1 -0
  8. package/moj/all.mjs +17 -110
  9. package/moj/all.mjs.map +1 -1
  10. package/moj/all.scss +3 -0
  11. package/moj/all.scss.map +1 -0
  12. package/moj/common/index.mjs +57 -0
  13. package/moj/common/index.mjs.map +1 -0
  14. package/moj/common/moj-frontend-version.mjs +14 -0
  15. package/moj/common/moj-frontend-version.mjs.map +1 -0
  16. package/moj/components/_all.scss +2 -0
  17. package/moj/components/_all.scss.map +1 -0
  18. package/moj/components/action-bar/_action-bar.scss +2 -0
  19. package/moj/components/action-bar/_action-bar.scss.map +1 -0
  20. package/moj/components/add-another/_add-another.scss +2 -0
  21. package/moj/components/add-another/_add-another.scss.map +1 -0
  22. package/moj/components/add-another/add-another.bundle.js +157 -0
  23. package/moj/components/add-another/add-another.bundle.js.map +1 -0
  24. package/moj/components/add-another/add-another.bundle.mjs +271 -0
  25. package/moj/components/add-another/add-another.bundle.mjs.map +1 -0
  26. package/moj/components/add-another/add-another.mjs +135 -91
  27. package/moj/components/add-another/add-another.mjs.map +1 -1
  28. package/moj/components/alert/_alert.scss +4 -0
  29. package/moj/components/alert/_alert.scss.map +1 -0
  30. package/moj/components/alert/alert.bundle.js +254 -0
  31. package/moj/components/alert/alert.bundle.js.map +1 -0
  32. package/moj/components/alert/alert.bundle.mjs +490 -0
  33. package/moj/components/alert/alert.bundle.mjs.map +1 -0
  34. package/moj/components/alert/alert.mjs +97 -218
  35. package/moj/components/alert/alert.mjs.map +1 -1
  36. package/moj/components/alert/{alert.spec.helper.js → alert.spec.helper.bundle.js} +1 -1
  37. package/moj/components/alert/alert.spec.helper.bundle.js.map +1 -0
  38. package/moj/components/alert/alert.spec.helper.bundle.mjs +67 -0
  39. package/moj/components/alert/alert.spec.helper.bundle.mjs.map +1 -0
  40. package/moj/components/alert/alert.spec.helper.mjs.map +1 -1
  41. package/moj/components/badge/_badge.scss +2 -0
  42. package/moj/components/badge/_badge.scss.map +1 -0
  43. package/moj/components/banner/_banner.scss +2 -0
  44. package/moj/components/banner/_banner.scss.map +1 -0
  45. package/moj/components/button-menu/README.md +12 -6
  46. package/moj/components/button-menu/_button-menu.scss +4 -1
  47. package/moj/components/button-menu/_button-menu.scss.map +1 -0
  48. package/moj/components/button-menu/button-menu.bundle.js +270 -0
  49. package/moj/components/button-menu/button-menu.bundle.js.map +1 -0
  50. package/moj/components/button-menu/button-menu.bundle.mjs +506 -0
  51. package/moj/components/button-menu/button-menu.bundle.mjs.map +1 -0
  52. package/moj/components/button-menu/button-menu.mjs +214 -280
  53. package/moj/components/button-menu/button-menu.mjs.map +1 -1
  54. package/moj/components/cookie-banner/_cookie-banner.scss +2 -0
  55. package/moj/components/cookie-banner/_cookie-banner.scss.map +1 -0
  56. package/moj/components/currency-input/_currency-input.scss +2 -0
  57. package/moj/components/currency-input/_currency-input.scss.map +1 -0
  58. package/moj/components/date-picker/_date-picker.scss +2 -0
  59. package/moj/components/date-picker/_date-picker.scss.map +1 -0
  60. package/moj/components/date-picker/date-picker.bundle.js +804 -0
  61. package/moj/components/date-picker/date-picker.bundle.js.map +1 -0
  62. package/moj/components/date-picker/date-picker.bundle.mjs +1040 -0
  63. package/moj/components/date-picker/date-picker.bundle.mjs.map +1 -0
  64. package/moj/components/date-picker/date-picker.mjs +663 -827
  65. package/moj/components/date-picker/date-picker.mjs.map +1 -1
  66. package/moj/components/filter/_filter.scss +2 -0
  67. package/moj/components/filter/_filter.scss.map +1 -0
  68. package/moj/components/filter/template.njk +1 -1
  69. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js +185 -0
  70. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js.map +1 -0
  71. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs +421 -0
  72. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs.map +1 -0
  73. package/moj/components/filter-toggle-button/filter-toggle-button.mjs +166 -81
  74. package/moj/components/filter-toggle-button/filter-toggle-button.mjs.map +1 -1
  75. package/moj/components/form-validator/form-validator.bundle.js +288 -0
  76. package/moj/components/form-validator/form-validator.bundle.js.map +1 -0
  77. package/moj/components/form-validator/form-validator.bundle.mjs +524 -0
  78. package/moj/components/form-validator/form-validator.bundle.mjs.map +1 -0
  79. package/moj/components/form-validator/form-validator.mjs +226 -149
  80. package/moj/components/form-validator/form-validator.mjs.map +1 -1
  81. package/moj/components/header/_header.scss +2 -0
  82. package/moj/components/header/_header.scss.map +1 -0
  83. package/moj/components/identity-bar/_identity-bar.scss +2 -0
  84. package/moj/components/identity-bar/_identity-bar.scss.map +1 -0
  85. package/moj/components/interruption-card/_interruption-card.scss +2 -0
  86. package/moj/components/interruption-card/_interruption-card.scss.map +1 -0
  87. package/moj/components/messages/_messages.scss +2 -0
  88. package/moj/components/messages/_messages.scss.map +1 -0
  89. package/moj/components/multi-file-upload/_multi-file-upload.scss +2 -0
  90. package/moj/components/multi-file-upload/_multi-file-upload.scss.map +1 -0
  91. package/moj/components/multi-file-upload/multi-file-upload.bundle.js +397 -0
  92. package/moj/components/multi-file-upload/multi-file-upload.bundle.js.map +1 -0
  93. package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs +633 -0
  94. package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs.map +1 -0
  95. package/moj/components/multi-file-upload/multi-file-upload.mjs +384 -213
  96. package/moj/components/multi-file-upload/multi-file-upload.mjs.map +1 -1
  97. package/moj/components/multi-file-upload/template.njk +1 -1
  98. package/moj/components/multi-select/_multi-select.scss +2 -0
  99. package/moj/components/multi-select/_multi-select.scss.map +1 -0
  100. package/moj/components/multi-select/multi-select.bundle.js +143 -0
  101. package/moj/components/multi-select/multi-select.bundle.js.map +1 -0
  102. package/moj/components/multi-select/multi-select.bundle.mjs +379 -0
  103. package/moj/components/multi-select/multi-select.bundle.mjs.map +1 -0
  104. package/moj/components/multi-select/multi-select.mjs +123 -64
  105. package/moj/components/multi-select/multi-select.mjs.map +1 -1
  106. package/moj/components/notification-badge/_notification-badge.scss +2 -0
  107. package/moj/components/notification-badge/_notification-badge.scss.map +1 -0
  108. package/moj/components/organisation-switcher/_organisation-switcher.scss +2 -0
  109. package/moj/components/organisation-switcher/_organisation-switcher.scss.map +1 -0
  110. package/moj/components/page-header-actions/_page-header-actions.scss +2 -0
  111. package/moj/components/page-header-actions/_page-header-actions.scss.map +1 -0
  112. package/moj/components/pagination/_pagination.scss +2 -2
  113. package/moj/components/pagination/_pagination.scss.map +1 -0
  114. package/moj/components/password-reveal/_password-reveal.scss +5 -1
  115. package/moj/components/password-reveal/_password-reveal.scss.map +1 -0
  116. package/moj/components/password-reveal/password-reveal.bundle.js +52 -0
  117. package/moj/components/password-reveal/password-reveal.bundle.js.map +1 -0
  118. package/moj/components/password-reveal/password-reveal.bundle.mjs +166 -0
  119. package/moj/components/password-reveal/password-reveal.bundle.mjs.map +1 -0
  120. package/moj/components/password-reveal/password-reveal.mjs +39 -29
  121. package/moj/components/password-reveal/password-reveal.mjs.map +1 -1
  122. package/moj/components/primary-navigation/_primary-navigation.scss +2 -0
  123. package/moj/components/primary-navigation/_primary-navigation.scss.map +1 -0
  124. package/moj/components/progress-bar/_progress-bar.scss +2 -0
  125. package/moj/components/progress-bar/_progress-bar.scss.map +1 -0
  126. package/moj/components/rich-text-editor/README.md +16 -9
  127. package/moj/components/rich-text-editor/_rich-text-editor.scss +2 -0
  128. package/moj/components/rich-text-editor/_rich-text-editor.scss.map +1 -0
  129. package/moj/components/rich-text-editor/rich-text-editor.bundle.js +210 -0
  130. package/moj/components/rich-text-editor/rich-text-editor.bundle.js.map +1 -0
  131. package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs +446 -0
  132. package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs.map +1 -0
  133. package/moj/components/rich-text-editor/rich-text-editor.mjs +186 -140
  134. package/moj/components/rich-text-editor/rich-text-editor.mjs.map +1 -1
  135. package/moj/components/search/_search.scss +2 -0
  136. package/moj/components/search/_search.scss.map +1 -0
  137. package/moj/components/search-toggle/{search-toggle.scss → _search-toggle.scss} +2 -0
  138. package/moj/components/search-toggle/_search-toggle.scss.map +1 -0
  139. package/moj/components/search-toggle/search-toggle.bundle.js +122 -0
  140. package/moj/components/search-toggle/search-toggle.bundle.js.map +1 -0
  141. package/moj/components/search-toggle/search-toggle.bundle.mjs +358 -0
  142. package/moj/components/search-toggle/search-toggle.bundle.mjs.map +1 -0
  143. package/moj/components/search-toggle/search-toggle.mjs +104 -43
  144. package/moj/components/search-toggle/search-toggle.mjs.map +1 -1
  145. package/moj/components/side-navigation/_side-navigation.scss +2 -0
  146. package/moj/components/side-navigation/_side-navigation.scss.map +1 -0
  147. package/moj/components/sortable-table/_sortable-table.scss +2 -2
  148. package/moj/components/sortable-table/_sortable-table.scss.map +1 -0
  149. package/moj/components/sortable-table/sortable-table.bundle.js +202 -0
  150. package/moj/components/sortable-table/sortable-table.bundle.js.map +1 -0
  151. package/moj/components/sortable-table/sortable-table.bundle.mjs +438 -0
  152. package/moj/components/sortable-table/sortable-table.bundle.mjs.map +1 -0
  153. package/moj/components/sortable-table/sortable-table.mjs +179 -122
  154. package/moj/components/sortable-table/sortable-table.mjs.map +1 -1
  155. package/moj/components/sub-navigation/_sub-navigation.scss +2 -0
  156. package/moj/components/sub-navigation/_sub-navigation.scss.map +1 -0
  157. package/moj/components/tag/_tag.scss +2 -0
  158. package/moj/components/tag/_tag.scss.map +1 -0
  159. package/moj/components/task-list/_task-list.scss +2 -0
  160. package/moj/components/task-list/_task-list.scss.map +1 -0
  161. package/moj/components/ticket-panel/_ticket-panel.scss +2 -0
  162. package/moj/components/ticket-panel/_ticket-panel.scss.map +1 -0
  163. package/moj/components/timeline/_timeline.scss +2 -0
  164. package/moj/components/timeline/_timeline.scss.map +1 -0
  165. package/moj/core/_all.scss +3 -0
  166. package/moj/core/_all.scss.map +1 -0
  167. package/moj/core/_moj-frontend-properties.scss +7 -0
  168. package/moj/core/_moj-frontend-properties.scss.map +1 -0
  169. package/moj/filters/all.js +44 -22
  170. package/moj/filters/prototype-kit-13-filters.js +4 -3
  171. package/moj/helpers/_all.scss +2 -0
  172. package/moj/helpers/_all.scss.map +1 -0
  173. package/moj/helpers/_hidden.scss +2 -0
  174. package/moj/helpers/_hidden.scss.map +1 -0
  175. package/moj/helpers/_links.scss +2 -0
  176. package/moj/helpers/_links.scss.map +1 -0
  177. package/moj/helpers.bundle.js +140 -0
  178. package/moj/helpers.bundle.js.map +1 -0
  179. package/moj/helpers.bundle.mjs +128 -0
  180. package/moj/helpers.bundle.mjs.map +1 -0
  181. package/moj/helpers.mjs +50 -77
  182. package/moj/helpers.mjs.map +1 -1
  183. package/moj/init.js +11 -2
  184. package/moj/moj-frontend.min.css +1 -1
  185. package/moj/moj-frontend.min.css.map +1 -1
  186. package/moj/moj-frontend.min.js +1 -1
  187. package/moj/moj-frontend.min.js.map +1 -1
  188. package/moj/objects/_all.scss +2 -0
  189. package/moj/objects/_all.scss.map +1 -0
  190. package/moj/objects/_button-group.scss +2 -0
  191. package/moj/objects/_button-group.scss.map +1 -0
  192. package/moj/objects/_filter-layout.scss +2 -0
  193. package/moj/objects/_filter-layout.scss.map +1 -0
  194. package/moj/objects/_scrollable-pane.scss +2 -0
  195. package/moj/objects/_scrollable-pane.scss.map +1 -0
  196. package/moj/objects/_width-container.scss +2 -0
  197. package/moj/objects/_width-container.scss.map +1 -0
  198. package/moj/settings/_all.scss +2 -0
  199. package/moj/settings/_all.scss.map +1 -0
  200. package/moj/settings/_assets.scss +2 -0
  201. package/moj/settings/_assets.scss.map +1 -0
  202. package/moj/settings/_colours.scss +2 -0
  203. package/moj/settings/_colours.scss.map +1 -0
  204. package/moj/settings/_measurements.scss +2 -0
  205. package/moj/settings/_measurements.scss.map +1 -0
  206. package/moj/settings/_typography.scss +2 -0
  207. package/moj/settings/_typography.scss.map +1 -0
  208. package/moj/template.njk +13 -0
  209. package/moj/utilities/_all.scss +2 -0
  210. package/moj/utilities/_all.scss.map +1 -0
  211. package/moj/utilities/_hidden.scss +2 -0
  212. package/moj/utilities/_hidden.scss.map +1 -0
  213. package/moj/utilities/_width-container.scss +2 -0
  214. package/moj/utilities/_width-container.scss.map +1 -0
  215. package/moj/vendor/govuk-frontend/_base.scss +2 -0
  216. package/moj/vendor/govuk-frontend/_base.scss.map +1 -0
  217. package/moj/vendor/govuk-frontend/_index.scss +2 -0
  218. package/moj/vendor/govuk-frontend/_index.scss.map +1 -0
  219. package/package.json +5 -6
  220. package/moj/all.jquery.min.js +0 -1
  221. package/moj/all.jquery.min.js.map +0 -1
  222. package/moj/all.js +0 -2662
  223. package/moj/all.js.map +0 -1
  224. package/moj/components/add-another/add-another.js +0 -115
  225. package/moj/components/add-another/add-another.js.map +0 -1
  226. package/moj/components/alert/alert.js +0 -356
  227. package/moj/components/alert/alert.js.map +0 -1
  228. package/moj/components/alert/alert.spec.helper.js.map +0 -1
  229. package/moj/components/button-menu/button-menu.js +0 -338
  230. package/moj/components/button-menu/button-menu.js.map +0 -1
  231. package/moj/components/date-picker/date-picker.js +0 -970
  232. package/moj/components/date-picker/date-picker.js.map +0 -1
  233. package/moj/components/filter-toggle-button/filter-toggle-button.js +0 -102
  234. package/moj/components/filter-toggle-button/filter-toggle-button.js.map +0 -1
  235. package/moj/components/form-validator/form-validator.js +0 -205
  236. package/moj/components/form-validator/form-validator.js.map +0 -1
  237. package/moj/components/multi-file-upload/multi-file-upload.js +0 -241
  238. package/moj/components/multi-file-upload/multi-file-upload.js.map +0 -1
  239. package/moj/components/multi-select/multi-select.js +0 -86
  240. package/moj/components/multi-select/multi-select.js.map +0 -1
  241. package/moj/components/password-reveal/password-reveal.js +0 -44
  242. package/moj/components/password-reveal/password-reveal.js.map +0 -1
  243. package/moj/components/rich-text-editor/rich-text-editor.js +0 -166
  244. package/moj/components/rich-text-editor/rich-text-editor.js.map +0 -1
  245. package/moj/components/search-toggle/search-toggle.js +0 -63
  246. package/moj/components/search-toggle/search-toggle.js.map +0 -1
  247. package/moj/components/sortable-table/sortable-table.js +0 -147
  248. package/moj/components/sortable-table/sortable-table.js.map +0 -1
  249. package/moj/helpers.js +0 -200
  250. package/moj/helpers.js.map +0 -1
  251. package/moj/vendor/html5shiv.js +0 -326
  252. package/moj/vendor/jquery.js +0 -9300
  253. package/moj/version.js +0 -12
  254. package/moj/version.js.map +0 -1
  255. package/moj/version.mjs +0 -4
  256. package/moj/version.mjs.map +0 -1
@@ -0,0 +1,506 @@
1
+ function isInitialised($root, moduleName) {
2
+ return $root instanceof HTMLElement && $root.hasAttribute(`data-${moduleName}-init`);
3
+ }
4
+
5
+ /**
6
+ * Checks if GOV.UK Frontend is supported on this page
7
+ *
8
+ * Some browsers will load and run our JavaScript but GOV.UK Frontend
9
+ * won't be supported.
10
+ *
11
+ * @param {HTMLElement | null} [$scope] - (internal) `<body>` HTML element checked for browser support
12
+ * @returns {boolean} Whether GOV.UK Frontend is supported on this page
13
+ */
14
+ function isSupported($scope = document.body) {
15
+ if (!$scope) {
16
+ return false;
17
+ }
18
+ return $scope.classList.contains('govuk-frontend-supported');
19
+ }
20
+ function isArray(option) {
21
+ return Array.isArray(option);
22
+ }
23
+ function isObject(option) {
24
+ return !!option && typeof option === 'object' && !isArray(option);
25
+ }
26
+ function formatErrorMessage(Component, message) {
27
+ return `${Component.moduleName}: ${message}`;
28
+ }
29
+
30
+ class GOVUKFrontendError extends Error {
31
+ constructor(...args) {
32
+ super(...args);
33
+ this.name = 'GOVUKFrontendError';
34
+ }
35
+ }
36
+ class SupportError extends GOVUKFrontendError {
37
+ /**
38
+ * Checks if GOV.UK Frontend is supported on this page
39
+ *
40
+ * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support
41
+ */
42
+ constructor($scope = document.body) {
43
+ const supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class="govuk-frontend-supported">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';
44
+ super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type="module">`');
45
+ this.name = 'SupportError';
46
+ }
47
+ }
48
+ class ConfigError extends GOVUKFrontendError {
49
+ constructor(...args) {
50
+ super(...args);
51
+ this.name = 'ConfigError';
52
+ }
53
+ }
54
+ class ElementError extends GOVUKFrontendError {
55
+ constructor(messageOrOptions) {
56
+ let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';
57
+ if (typeof messageOrOptions === 'object') {
58
+ const {
59
+ component,
60
+ identifier,
61
+ element,
62
+ expectedType
63
+ } = messageOrOptions;
64
+ message = identifier;
65
+ message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';
66
+ message = formatErrorMessage(component, message);
67
+ }
68
+ super(message);
69
+ this.name = 'ElementError';
70
+ }
71
+ }
72
+ class InitError extends GOVUKFrontendError {
73
+ constructor(componentOrMessage) {
74
+ const message = typeof componentOrMessage === 'string' ? componentOrMessage : formatErrorMessage(componentOrMessage, `Root element (\`$root\`) already initialised`);
75
+ super(message);
76
+ this.name = 'InitError';
77
+ }
78
+ }
79
+
80
+ class Component {
81
+ /**
82
+ * Returns the root element of the component
83
+ *
84
+ * @protected
85
+ * @returns {RootElementType} - the root element of component
86
+ */
87
+ get $root() {
88
+ return this._$root;
89
+ }
90
+ constructor($root) {
91
+ this._$root = void 0;
92
+ const childConstructor = this.constructor;
93
+ if (typeof childConstructor.moduleName !== 'string') {
94
+ throw new InitError(`\`moduleName\` not defined in component`);
95
+ }
96
+ if (!($root instanceof childConstructor.elementType)) {
97
+ throw new ElementError({
98
+ element: $root,
99
+ component: childConstructor,
100
+ identifier: 'Root element (`$root`)',
101
+ expectedType: childConstructor.elementType.name
102
+ });
103
+ } else {
104
+ this._$root = $root;
105
+ }
106
+ childConstructor.checkSupport();
107
+ this.checkInitialised();
108
+ const moduleName = childConstructor.moduleName;
109
+ this.$root.setAttribute(`data-${moduleName}-init`, '');
110
+ }
111
+ checkInitialised() {
112
+ const constructor = this.constructor;
113
+ const moduleName = constructor.moduleName;
114
+ if (moduleName && isInitialised(this.$root, moduleName)) {
115
+ throw new InitError(constructor);
116
+ }
117
+ }
118
+ static checkSupport() {
119
+ if (!isSupported()) {
120
+ throw new SupportError();
121
+ }
122
+ }
123
+ }
124
+
125
+ /**
126
+ * @typedef ChildClass
127
+ * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component
128
+ */
129
+
130
+ /**
131
+ * @typedef {typeof Component & ChildClass} ChildClassConstructor
132
+ */
133
+ Component.elementType = HTMLElement;
134
+
135
+ const configOverride = Symbol.for('configOverride');
136
+ class ConfigurableComponent extends Component {
137
+ [configOverride](param) {
138
+ return {};
139
+ }
140
+
141
+ /**
142
+ * Returns the root element of the component
143
+ *
144
+ * @protected
145
+ * @returns {ConfigurationType} - the root element of component
146
+ */
147
+ get config() {
148
+ return this._config;
149
+ }
150
+ constructor($root, config) {
151
+ super($root);
152
+ this._config = void 0;
153
+ const childConstructor = this.constructor;
154
+ if (!isObject(childConstructor.defaults)) {
155
+ throw new ConfigError(formatErrorMessage(childConstructor, 'Config passed as parameter into constructor but no defaults defined'));
156
+ }
157
+ const datasetConfig = normaliseDataset(childConstructor, this._$root.dataset);
158
+ this._config = mergeConfigs(childConstructor.defaults, config != null ? config : {}, this[configOverride](datasetConfig), datasetConfig);
159
+ }
160
+ }
161
+ function normaliseString(value, property) {
162
+ const trimmedValue = value ? value.trim() : '';
163
+ let output;
164
+ let outputType = property == null ? void 0 : property.type;
165
+ if (!outputType) {
166
+ if (['true', 'false'].includes(trimmedValue)) {
167
+ outputType = 'boolean';
168
+ }
169
+ if (trimmedValue.length > 0 && isFinite(Number(trimmedValue))) {
170
+ outputType = 'number';
171
+ }
172
+ }
173
+ switch (outputType) {
174
+ case 'boolean':
175
+ output = trimmedValue === 'true';
176
+ break;
177
+ case 'number':
178
+ output = Number(trimmedValue);
179
+ break;
180
+ default:
181
+ output = value;
182
+ }
183
+ return output;
184
+ }
185
+ function normaliseDataset(Component, dataset) {
186
+ if (!isObject(Component.schema)) {
187
+ throw new ConfigError(formatErrorMessage(Component, 'Config passed as parameter into constructor but no schema defined'));
188
+ }
189
+ const out = {};
190
+ const entries = Object.entries(Component.schema.properties);
191
+ for (const entry of entries) {
192
+ const [namespace, property] = entry;
193
+ const field = namespace.toString();
194
+ if (field in dataset) {
195
+ out[field] = normaliseString(dataset[field], property);
196
+ }
197
+ if ((property == null ? void 0 : property.type) === 'object') {
198
+ out[field] = extractConfigByNamespace(Component.schema, dataset, namespace);
199
+ }
200
+ }
201
+ return out;
202
+ }
203
+ function mergeConfigs(...configObjects) {
204
+ const formattedConfigObject = {};
205
+ for (const configObject of configObjects) {
206
+ for (const key of Object.keys(configObject)) {
207
+ const option = formattedConfigObject[key];
208
+ const override = configObject[key];
209
+ if (isObject(option) && isObject(override)) {
210
+ formattedConfigObject[key] = mergeConfigs(option, override);
211
+ } else {
212
+ formattedConfigObject[key] = override;
213
+ }
214
+ }
215
+ }
216
+ return formattedConfigObject;
217
+ }
218
+ function extractConfigByNamespace(schema, dataset, namespace) {
219
+ const property = schema.properties[namespace];
220
+ if ((property == null ? void 0 : property.type) !== 'object') {
221
+ return;
222
+ }
223
+ const newObject = {
224
+ [namespace]: {}
225
+ };
226
+ for (const [key, value] of Object.entries(dataset)) {
227
+ let current = newObject;
228
+ const keyParts = key.split('.');
229
+ for (const [index, name] of keyParts.entries()) {
230
+ if (isObject(current)) {
231
+ if (index < keyParts.length - 1) {
232
+ if (!isObject(current[name])) {
233
+ current[name] = {};
234
+ }
235
+ current = current[name];
236
+ } else if (key !== namespace) {
237
+ current[name] = normaliseString(value);
238
+ }
239
+ }
240
+ }
241
+ }
242
+ return newObject[namespace];
243
+ }
244
+
245
+ /**
246
+ * @augments {ConfigurableComponent<ButtonMenuConfig>}
247
+ */
248
+ class ButtonMenu extends ConfigurableComponent {
249
+ /**
250
+ * @param {Element | null} $root - HTML element to use for button menu
251
+ * @param {ButtonMenuConfig} [config] - Button menu config
252
+ */
253
+ constructor($root, config = {}) {
254
+ super($root, config);
255
+
256
+ // If only one button is provided, don't initiate a menu and toggle button
257
+ // if classes have been provided for the toggleButton, apply them to the single item
258
+ if (this.$root.children.length === 1) {
259
+ const $button = this.$root.children[0];
260
+ $button.classList.forEach(className => {
261
+ if (className.startsWith('govuk-button-')) {
262
+ $button.classList.remove(className);
263
+ }
264
+ $button.classList.remove('moj-button-menu__item');
265
+ $button.classList.add('moj-button-menu__single-button');
266
+ });
267
+ if (this.config.buttonClasses) {
268
+ $button.classList.add(...this.config.buttonClasses.split(' '));
269
+ }
270
+ }
271
+ // Otherwise initialise a button menu
272
+ if (this.$root.children.length > 1) {
273
+ this.initMenu();
274
+ }
275
+ }
276
+ initMenu() {
277
+ this.$menu = this.createMenu();
278
+ this.$root.insertAdjacentHTML('afterbegin', this.toggleTemplate());
279
+ this.setupMenuItems();
280
+ this.$menuToggle = this.$root.querySelector(':scope > button');
281
+ this.$items = this.$menu.querySelectorAll('a, button');
282
+ this.$menuToggle.addEventListener('click', event => {
283
+ this.toggleMenu(event);
284
+ });
285
+ this.$root.addEventListener('keydown', event => {
286
+ this.handleKeyDown(event);
287
+ });
288
+ document.addEventListener('click', event => {
289
+ if (event.target instanceof Node && !this.$root.contains(event.target)) {
290
+ this.closeMenu(false);
291
+ }
292
+ });
293
+ }
294
+ createMenu() {
295
+ const $menu = document.createElement('ul');
296
+ $menu.setAttribute('role', 'list');
297
+ $menu.hidden = true;
298
+ $menu.classList.add('moj-button-menu__wrapper');
299
+ if (this.config.alignMenu === 'right') {
300
+ $menu.classList.add('moj-button-menu__wrapper--right');
301
+ }
302
+ this.$root.appendChild($menu);
303
+ while (this.$root.firstChild !== $menu) {
304
+ $menu.appendChild(this.$root.firstChild);
305
+ }
306
+ return $menu;
307
+ }
308
+ setupMenuItems() {
309
+ Array.from(this.$menu.children).forEach($menuItem => {
310
+ // wrap item in li tag
311
+ const $listItem = document.createElement('li');
312
+ this.$menu.insertBefore($listItem, $menuItem);
313
+ $listItem.appendChild($menuItem);
314
+ $menuItem.setAttribute('tabindex', '-1');
315
+ if ($menuItem.tagName === 'BUTTON') {
316
+ $menuItem.setAttribute('type', 'button');
317
+ }
318
+ $menuItem.classList.forEach(className => {
319
+ if (className.startsWith('govuk-button')) {
320
+ $menuItem.classList.remove(className);
321
+ }
322
+ });
323
+
324
+ // add a slight delay after click before closing the menu, makes it *feel* better
325
+ $menuItem.addEventListener('click', () => {
326
+ setTimeout(() => {
327
+ this.closeMenu(false);
328
+ }, 50);
329
+ });
330
+ });
331
+ }
332
+ toggleTemplate() {
333
+ return `
334
+ <button type="button" class="govuk-button moj-button-menu__toggle-button ${this.config.buttonClasses || ''}" aria-haspopup="true" aria-expanded="false">
335
+ <span>
336
+ ${this.config.buttonText}
337
+ <svg width="11" height="5" viewBox="0 0 11 5" xmlns="http://www.w3.org/2000/svg">
338
+ <path d="M5.5 0L11 5L0 5L5.5 0Z" fill="currentColor"/>
339
+ </svg>
340
+ </span>
341
+ </button>`;
342
+ }
343
+
344
+ /**
345
+ * @returns {boolean}
346
+ */
347
+ isOpen() {
348
+ return this.$menuToggle.getAttribute('aria-expanded') === 'true';
349
+ }
350
+
351
+ /**
352
+ * @param {MouseEvent} event - Click event
353
+ */
354
+ toggleMenu(event) {
355
+ event.preventDefault();
356
+
357
+ // If menu is triggered with mouse don't move focus to first item
358
+ const keyboardEvent = event.detail === 0;
359
+ const focusIndex = keyboardEvent ? 0 : -1;
360
+ if (this.isOpen()) {
361
+ this.closeMenu();
362
+ } else {
363
+ this.openMenu(focusIndex);
364
+ }
365
+ }
366
+
367
+ /**
368
+ * Opens the menu and optionally sets the focus to the item with given index
369
+ *
370
+ * @param {number} focusIndex - The index of the item to focus
371
+ */
372
+ openMenu(focusIndex = 0) {
373
+ this.$menu.hidden = false;
374
+ this.$menuToggle.setAttribute('aria-expanded', 'true');
375
+ if (focusIndex !== -1) {
376
+ this.focusItem(focusIndex);
377
+ }
378
+ }
379
+
380
+ /**
381
+ * Closes the menu and optionally returns focus back to menuToggle
382
+ *
383
+ * @param {boolean} moveFocus - whether to return focus to the toggle button
384
+ */
385
+ closeMenu(moveFocus = true) {
386
+ this.$menu.hidden = true;
387
+ this.$menuToggle.setAttribute('aria-expanded', 'false');
388
+ if (moveFocus) {
389
+ this.$menuToggle.focus();
390
+ }
391
+ }
392
+
393
+ /**
394
+ * Focuses the menu item at the specified index
395
+ *
396
+ * @param {number} index - the index of the item to focus
397
+ */
398
+ focusItem(index) {
399
+ if (index >= this.$items.length) index = 0;
400
+ if (index < 0) index = this.$items.length - 1;
401
+ const $menuItem = this.$items.item(index);
402
+ if ($menuItem) {
403
+ $menuItem.focus();
404
+ }
405
+ }
406
+ currentFocusIndex() {
407
+ const $activeElement = document.activeElement;
408
+ const $menuItems = Array.from(this.$items);
409
+ return ($activeElement instanceof HTMLAnchorElement || $activeElement instanceof HTMLButtonElement) && $menuItems.indexOf($activeElement);
410
+ }
411
+
412
+ /**
413
+ * @param {KeyboardEvent} event - Keydown event
414
+ */
415
+ handleKeyDown(event) {
416
+ if (event.target === this.$menuToggle) {
417
+ switch (event.key) {
418
+ case 'ArrowDown':
419
+ event.preventDefault();
420
+ this.openMenu();
421
+ break;
422
+ case 'ArrowUp':
423
+ event.preventDefault();
424
+ this.openMenu(this.$items.length - 1);
425
+ break;
426
+ }
427
+ }
428
+ if (event.target instanceof Node && this.$menu.contains(event.target) && this.isOpen()) {
429
+ switch (event.key) {
430
+ case 'ArrowDown':
431
+ event.preventDefault();
432
+ if (this.currentFocusIndex() !== -1) {
433
+ this.focusItem(this.currentFocusIndex() + 1);
434
+ }
435
+ break;
436
+ case 'ArrowUp':
437
+ event.preventDefault();
438
+ if (this.currentFocusIndex() !== -1) {
439
+ this.focusItem(this.currentFocusIndex() - 1);
440
+ }
441
+ break;
442
+ case 'Home':
443
+ event.preventDefault();
444
+ this.focusItem(0);
445
+ break;
446
+ case 'End':
447
+ event.preventDefault();
448
+ this.focusItem(this.$items.length - 1);
449
+ break;
450
+ }
451
+ }
452
+ if (event.key === 'Escape' && this.isOpen()) {
453
+ this.closeMenu();
454
+ }
455
+ if (event.key === 'Tab' && this.isOpen()) {
456
+ this.closeMenu(false);
457
+ }
458
+ }
459
+
460
+ /**
461
+ * Name for the component used when initialising using data-module attributes.
462
+ */
463
+ }
464
+
465
+ /**
466
+ * @typedef {object} ButtonMenuConfig
467
+ * @property {string} [buttonText='Actions'] - Label for the toggle button
468
+ * @property {"left" | "right"} [alignMenu='left'] - the alignment of the menu
469
+ * @property {string} [buttonClasses='govuk-button--secondary'] - css classes applied to the toggle button
470
+ */
471
+
472
+ /**
473
+ * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'
474
+ */
475
+ ButtonMenu.moduleName = 'moj-button-menu';
476
+ /**
477
+ * Button menu config
478
+ *
479
+ * @type {ButtonMenuConfig}
480
+ */
481
+ ButtonMenu.defaults = Object.freeze({
482
+ buttonText: 'Actions',
483
+ alignMenu: 'left',
484
+ buttonClasses: ''
485
+ });
486
+ /**
487
+ * Button menu config schema
488
+ *
489
+ * @type {Schema<ButtonMenuConfig>}
490
+ */
491
+ ButtonMenu.schema = Object.freeze(/** @type {const} */{
492
+ properties: {
493
+ buttonText: {
494
+ type: 'string'
495
+ },
496
+ buttonClasses: {
497
+ type: 'string'
498
+ },
499
+ alignMenu: {
500
+ type: 'string'
501
+ }
502
+ }
503
+ });
504
+
505
+ export { ButtonMenu };
506
+ //# sourceMappingURL=button-menu.bundle.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button-menu.bundle.mjs","sources":["../../../../node_modules/govuk-frontend/dist/govuk/common/index.mjs","../../../../node_modules/govuk-frontend/dist/govuk/errors/index.mjs","../../../../node_modules/govuk-frontend/dist/govuk/component.mjs","../../../../node_modules/govuk-frontend/dist/govuk/common/configuration.mjs","../../../../src/moj/components/button-menu/button-menu.mjs"],"sourcesContent":["function getFragmentFromUrl(url) {\n if (!url.includes('#')) {\n return undefined;\n }\n return url.split('#').pop();\n}\nfunction getBreakpoint(name) {\n const property = `--govuk-frontend-breakpoint-${name}`;\n const value = window.getComputedStyle(document.documentElement).getPropertyValue(property);\n return {\n property,\n value: value || undefined\n };\n}\nfunction setFocus($element, options = {}) {\n var _options$onBeforeFocu;\n const isFocusable = $element.getAttribute('tabindex');\n if (!isFocusable) {\n $element.setAttribute('tabindex', '-1');\n }\n function onFocus() {\n $element.addEventListener('blur', onBlur, {\n once: true\n });\n }\n function onBlur() {\n var _options$onBlur;\n (_options$onBlur = options.onBlur) == null || _options$onBlur.call($element);\n if (!isFocusable) {\n $element.removeAttribute('tabindex');\n }\n }\n $element.addEventListener('focus', onFocus, {\n once: true\n });\n (_options$onBeforeFocu = options.onBeforeFocus) == null || _options$onBeforeFocu.call($element);\n $element.focus();\n}\nfunction isInitialised($root, moduleName) {\n return $root instanceof HTMLElement && $root.hasAttribute(`data-${moduleName}-init`);\n}\n\n/**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * Some browsers will load and run our JavaScript but GOV.UK Frontend\n * won't be supported.\n *\n * @param {HTMLElement | null} [$scope] - (internal) `<body>` HTML element checked for browser support\n * @returns {boolean} Whether GOV.UK Frontend is supported on this page\n */\nfunction isSupported($scope = document.body) {\n if (!$scope) {\n return false;\n }\n return $scope.classList.contains('govuk-frontend-supported');\n}\nfunction isArray(option) {\n return Array.isArray(option);\n}\nfunction isObject(option) {\n return !!option && typeof option === 'object' && !isArray(option);\n}\nfunction formatErrorMessage(Component, message) {\n return `${Component.moduleName}: ${message}`;\n}\n/**\n * @typedef ComponentWithModuleName\n * @property {string} moduleName - Name of the component\n */\n/**\n * @import { ObjectNested } from './configuration.mjs'\n */\n\nexport { formatErrorMessage, getBreakpoint, getFragmentFromUrl, isInitialised, isObject, isSupported, setFocus };\n//# sourceMappingURL=index.mjs.map\n","import { formatErrorMessage } from '../common/index.mjs';\n\nclass GOVUKFrontendError extends Error {\n constructor(...args) {\n super(...args);\n this.name = 'GOVUKFrontendError';\n }\n}\nclass SupportError extends GOVUKFrontendError {\n /**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support\n */\n constructor($scope = document.body) {\n const supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class=\"govuk-frontend-supported\">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';\n super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type=\"module\">`');\n this.name = 'SupportError';\n }\n}\nclass ConfigError extends GOVUKFrontendError {\n constructor(...args) {\n super(...args);\n this.name = 'ConfigError';\n }\n}\nclass ElementError extends GOVUKFrontendError {\n constructor(messageOrOptions) {\n let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';\n if (typeof messageOrOptions === 'object') {\n const {\n component,\n identifier,\n element,\n expectedType\n } = messageOrOptions;\n message = identifier;\n message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';\n message = formatErrorMessage(component, message);\n }\n super(message);\n this.name = 'ElementError';\n }\n}\nclass InitError extends GOVUKFrontendError {\n constructor(componentOrMessage) {\n const message = typeof componentOrMessage === 'string' ? componentOrMessage : formatErrorMessage(componentOrMessage, `Root element (\\`$root\\`) already initialised`);\n super(message);\n this.name = 'InitError';\n }\n}\n/**\n * @import { ComponentWithModuleName } from '../common/index.mjs'\n */\n\nexport { ConfigError, ElementError, GOVUKFrontendError, InitError, SupportError };\n//# sourceMappingURL=index.mjs.map\n","import { isInitialised, isSupported } from './common/index.mjs';\nimport { InitError, ElementError, SupportError } from './errors/index.mjs';\n\nclass Component {\n /**\n * Returns the root element of the component\n *\n * @protected\n * @returns {RootElementType} - the root element of component\n */\n get $root() {\n return this._$root;\n }\n constructor($root) {\n this._$root = void 0;\n const childConstructor = this.constructor;\n if (typeof childConstructor.moduleName !== 'string') {\n throw new InitError(`\\`moduleName\\` not defined in component`);\n }\n if (!($root instanceof childConstructor.elementType)) {\n throw new ElementError({\n element: $root,\n component: childConstructor,\n identifier: 'Root element (`$root`)',\n expectedType: childConstructor.elementType.name\n });\n } else {\n this._$root = $root;\n }\n childConstructor.checkSupport();\n this.checkInitialised();\n const moduleName = childConstructor.moduleName;\n this.$root.setAttribute(`data-${moduleName}-init`, '');\n }\n checkInitialised() {\n const constructor = this.constructor;\n const moduleName = constructor.moduleName;\n if (moduleName && isInitialised(this.$root, moduleName)) {\n throw new InitError(constructor);\n }\n }\n static checkSupport() {\n if (!isSupported()) {\n throw new SupportError();\n }\n }\n}\n\n/**\n * @typedef ChildClass\n * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component\n */\n\n/**\n * @typedef {typeof Component & ChildClass} ChildClassConstructor\n */\nComponent.elementType = HTMLElement;\n\nexport { Component };\n//# sourceMappingURL=component.mjs.map\n","import { Component } from '../component.mjs';\nimport { ConfigError } from '../errors/index.mjs';\nimport { isObject, formatErrorMessage } from './index.mjs';\n\nconst configOverride = Symbol.for('configOverride');\nclass ConfigurableComponent extends Component {\n [configOverride](param) {\n return {};\n }\n\n /**\n * Returns the root element of the component\n *\n * @protected\n * @returns {ConfigurationType} - the root element of component\n */\n get config() {\n return this._config;\n }\n constructor($root, config) {\n super($root);\n this._config = void 0;\n const childConstructor = this.constructor;\n if (!isObject(childConstructor.defaults)) {\n throw new ConfigError(formatErrorMessage(childConstructor, 'Config passed as parameter into constructor but no defaults defined'));\n }\n const datasetConfig = normaliseDataset(childConstructor, this._$root.dataset);\n this._config = mergeConfigs(childConstructor.defaults, config != null ? config : {}, this[configOverride](datasetConfig), datasetConfig);\n }\n}\nfunction normaliseString(value, property) {\n const trimmedValue = value ? value.trim() : '';\n let output;\n let outputType = property == null ? void 0 : property.type;\n if (!outputType) {\n if (['true', 'false'].includes(trimmedValue)) {\n outputType = 'boolean';\n }\n if (trimmedValue.length > 0 && isFinite(Number(trimmedValue))) {\n outputType = 'number';\n }\n }\n switch (outputType) {\n case 'boolean':\n output = trimmedValue === 'true';\n break;\n case 'number':\n output = Number(trimmedValue);\n break;\n default:\n output = value;\n }\n return output;\n}\nfunction normaliseDataset(Component, dataset) {\n if (!isObject(Component.schema)) {\n throw new ConfigError(formatErrorMessage(Component, 'Config passed as parameter into constructor but no schema defined'));\n }\n const out = {};\n const entries = Object.entries(Component.schema.properties);\n for (const entry of entries) {\n const [namespace, property] = entry;\n const field = namespace.toString();\n if (field in dataset) {\n out[field] = normaliseString(dataset[field], property);\n }\n if ((property == null ? void 0 : property.type) === 'object') {\n out[field] = extractConfigByNamespace(Component.schema, dataset, namespace);\n }\n }\n return out;\n}\nfunction mergeConfigs(...configObjects) {\n const formattedConfigObject = {};\n for (const configObject of configObjects) {\n for (const key of Object.keys(configObject)) {\n const option = formattedConfigObject[key];\n const override = configObject[key];\n if (isObject(option) && isObject(override)) {\n formattedConfigObject[key] = mergeConfigs(option, override);\n } else {\n formattedConfigObject[key] = override;\n }\n }\n }\n return formattedConfigObject;\n}\nfunction validateConfig(schema, config) {\n const validationErrors = [];\n for (const [name, conditions] of Object.entries(schema)) {\n const errors = [];\n if (Array.isArray(conditions)) {\n for (const {\n required,\n errorMessage\n } of conditions) {\n if (!required.every(key => !!config[key])) {\n errors.push(errorMessage);\n }\n }\n if (name === 'anyOf' && !(conditions.length - errors.length >= 1)) {\n validationErrors.push(...errors);\n }\n }\n }\n return validationErrors;\n}\nfunction extractConfigByNamespace(schema, dataset, namespace) {\n const property = schema.properties[namespace];\n if ((property == null ? void 0 : property.type) !== 'object') {\n return;\n }\n const newObject = {\n [namespace]: {}\n };\n for (const [key, value] of Object.entries(dataset)) {\n let current = newObject;\n const keyParts = key.split('.');\n for (const [index, name] of keyParts.entries()) {\n if (isObject(current)) {\n if (index < keyParts.length - 1) {\n if (!isObject(current[name])) {\n current[name] = {};\n }\n current = current[name];\n } else if (key !== namespace) {\n current[name] = normaliseString(value);\n }\n }\n }\n }\n return newObject[namespace];\n}\n/**\n * Schema for component config\n *\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType\n * @typedef {object} Schema\n * @property {Record<keyof ConfigurationType, SchemaProperty | undefined>} properties - Schema properties\n * @property {SchemaCondition<ConfigurationType>[]} [anyOf] - List of schema conditions\n */\n/**\n * Schema property for component config\n *\n * @typedef {object} SchemaProperty\n * @property {'string' | 'boolean' | 'number' | 'object'} type - Property type\n */\n/**\n * Schema condition for component config\n *\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType\n * @typedef {object} SchemaCondition\n * @property {(keyof ConfigurationType)[]} required - List of required config fields\n * @property {string} errorMessage - Error message when required config fields not provided\n */\n/**\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]\n * @typedef ChildClass\n * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component\n * @property {Schema<ConfigurationType>} [schema] - The schema of the component configuration\n * @property {ConfigurationType} [defaults] - The default values of the configuration of the component\n */\n/**\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]\n * @typedef {typeof Component & ChildClass<ConfigurationType>} ChildClassConstructor<ConfigurationType>\n */\n\nexport { ConfigurableComponent, configOverride, extractConfigByNamespace, mergeConfigs, normaliseDataset, normaliseString, validateConfig };\n//# sourceMappingURL=configuration.mjs.map\n","import { ConfigurableComponent } from 'govuk-frontend'\n\n/**\n * @augments {ConfigurableComponent<ButtonMenuConfig>}\n */\nexport class ButtonMenu extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for button menu\n * @param {ButtonMenuConfig} [config] - Button menu config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n // If only one button is provided, don't initiate a menu and toggle button\n // if classes have been provided for the toggleButton, apply them to the single item\n if (this.$root.children.length === 1) {\n const $button = this.$root.children[0]\n\n $button.classList.forEach((className) => {\n if (className.startsWith('govuk-button-')) {\n $button.classList.remove(className)\n }\n\n $button.classList.remove('moj-button-menu__item')\n $button.classList.add('moj-button-menu__single-button')\n })\n\n if (this.config.buttonClasses) {\n $button.classList.add(...this.config.buttonClasses.split(' '))\n }\n }\n // Otherwise initialise a button menu\n if (this.$root.children.length > 1) {\n this.initMenu()\n }\n }\n\n initMenu() {\n this.$menu = this.createMenu()\n this.$root.insertAdjacentHTML('afterbegin', this.toggleTemplate())\n this.setupMenuItems()\n\n this.$menuToggle = this.$root.querySelector(':scope > button')\n this.$items = this.$menu.querySelectorAll('a, button')\n\n this.$menuToggle.addEventListener('click', (event) => {\n this.toggleMenu(event)\n })\n\n this.$root.addEventListener('keydown', (event) => {\n this.handleKeyDown(event)\n })\n\n document.addEventListener('click', (event) => {\n if (event.target instanceof Node && !this.$root.contains(event.target)) {\n this.closeMenu(false)\n }\n })\n }\n\n createMenu() {\n const $menu = document.createElement('ul')\n\n $menu.setAttribute('role', 'list')\n $menu.hidden = true\n $menu.classList.add('moj-button-menu__wrapper')\n\n if (this.config.alignMenu === 'right') {\n $menu.classList.add('moj-button-menu__wrapper--right')\n }\n\n this.$root.appendChild($menu)\n\n while (this.$root.firstChild !== $menu) {\n $menu.appendChild(this.$root.firstChild)\n }\n\n return $menu\n }\n\n setupMenuItems() {\n Array.from(this.$menu.children).forEach(($menuItem) => {\n // wrap item in li tag\n const $listItem = document.createElement('li')\n this.$menu.insertBefore($listItem, $menuItem)\n $listItem.appendChild($menuItem)\n\n $menuItem.setAttribute('tabindex', '-1')\n\n if ($menuItem.tagName === 'BUTTON') {\n $menuItem.setAttribute('type', 'button')\n }\n\n $menuItem.classList.forEach((className) => {\n if (className.startsWith('govuk-button')) {\n $menuItem.classList.remove(className)\n }\n })\n\n // add a slight delay after click before closing the menu, makes it *feel* better\n $menuItem.addEventListener('click', () => {\n setTimeout(() => {\n this.closeMenu(false)\n }, 50)\n })\n })\n }\n\n toggleTemplate() {\n return `\n <button type=\"button\" class=\"govuk-button moj-button-menu__toggle-button ${this.config.buttonClasses || ''}\" aria-haspopup=\"true\" aria-expanded=\"false\">\n <span>\n ${this.config.buttonText}\n <svg width=\"11\" height=\"5\" viewBox=\"0 0 11 5\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5.5 0L11 5L0 5L5.5 0Z\" fill=\"currentColor\"/>\n </svg>\n </span>\n </button>`\n }\n\n /**\n * @returns {boolean}\n */\n isOpen() {\n return this.$menuToggle.getAttribute('aria-expanded') === 'true'\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n toggleMenu(event) {\n event.preventDefault()\n\n // If menu is triggered with mouse don't move focus to first item\n const keyboardEvent = event.detail === 0\n const focusIndex = keyboardEvent ? 0 : -1\n\n if (this.isOpen()) {\n this.closeMenu()\n } else {\n this.openMenu(focusIndex)\n }\n }\n\n /**\n * Opens the menu and optionally sets the focus to the item with given index\n *\n * @param {number} focusIndex - The index of the item to focus\n */\n openMenu(focusIndex = 0) {\n this.$menu.hidden = false\n this.$menuToggle.setAttribute('aria-expanded', 'true')\n if (focusIndex !== -1) {\n this.focusItem(focusIndex)\n }\n }\n\n /**\n * Closes the menu and optionally returns focus back to menuToggle\n *\n * @param {boolean} moveFocus - whether to return focus to the toggle button\n */\n closeMenu(moveFocus = true) {\n this.$menu.hidden = true\n this.$menuToggle.setAttribute('aria-expanded', 'false')\n if (moveFocus) {\n this.$menuToggle.focus()\n }\n }\n\n /**\n * Focuses the menu item at the specified index\n *\n * @param {number} index - the index of the item to focus\n */\n focusItem(index) {\n if (index >= this.$items.length) index = 0\n if (index < 0) index = this.$items.length - 1\n\n const $menuItem = this.$items.item(index)\n if ($menuItem) {\n $menuItem.focus()\n }\n }\n\n currentFocusIndex() {\n const $activeElement = document.activeElement\n const $menuItems = Array.from(this.$items)\n\n return (\n ($activeElement instanceof HTMLAnchorElement ||\n $activeElement instanceof HTMLButtonElement) &&\n $menuItems.indexOf($activeElement)\n )\n }\n\n /**\n * @param {KeyboardEvent} event - Keydown event\n */\n handleKeyDown(event) {\n if (event.target === this.$menuToggle) {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n this.openMenu()\n break\n case 'ArrowUp':\n event.preventDefault()\n this.openMenu(this.$items.length - 1)\n break\n }\n }\n\n if (\n event.target instanceof Node &&\n this.$menu.contains(event.target) &&\n this.isOpen()\n ) {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n if (this.currentFocusIndex() !== -1) {\n this.focusItem(this.currentFocusIndex() + 1)\n }\n break\n case 'ArrowUp':\n event.preventDefault()\n if (this.currentFocusIndex() !== -1) {\n this.focusItem(this.currentFocusIndex() - 1)\n }\n break\n case 'Home':\n event.preventDefault()\n this.focusItem(0)\n break\n case 'End':\n event.preventDefault()\n this.focusItem(this.$items.length - 1)\n break\n }\n }\n\n if (event.key === 'Escape' && this.isOpen()) {\n this.closeMenu()\n }\n if (event.key === 'Tab' && this.isOpen()) {\n this.closeMenu(false)\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-button-menu'\n\n /**\n * Button menu config\n *\n * @type {ButtonMenuConfig}\n */\n static defaults = Object.freeze({\n buttonText: 'Actions',\n alignMenu: 'left',\n buttonClasses: ''\n })\n\n /**\n * Button menu config schema\n *\n * @type {Schema<ButtonMenuConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n buttonText: { type: 'string' },\n buttonClasses: { type: 'string' },\n alignMenu: { type: 'string' }\n }\n })\n )\n}\n\n/**\n * @typedef {object} ButtonMenuConfig\n * @property {string} [buttonText='Actions'] - Label for the toggle button\n * @property {\"left\" | \"right\"} [alignMenu='left'] - the alignment of the menu\n * @property {string} [buttonClasses='govuk-button--secondary'] - css classes applied to the toggle button\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n"],"names":["isInitialised","$root","moduleName","HTMLElement","hasAttribute","isSupported","$scope","document","body","classList","contains","isArray","option","Array","isObject","formatErrorMessage","Component","message","GOVUKFrontendError","Error","constructor","args","name","SupportError","supportMessage","HTMLScriptElement","prototype","ConfigError","ElementError","messageOrOptions","component","identifier","element","expectedType","InitError","componentOrMessage","_$root","childConstructor","elementType","checkSupport","checkInitialised","setAttribute","configOverride","Symbol","for","ConfigurableComponent","param","config","_config","defaults","datasetConfig","normaliseDataset","dataset","mergeConfigs","normaliseString","value","property","trimmedValue","trim","output","outputType","type","includes","length","isFinite","Number","schema","out","entries","Object","properties","entry","namespace","field","toString","extractConfigByNamespace","configObjects","formattedConfigObject","configObject","key","keys","override","newObject","current","keyParts","split","index","ButtonMenu","children","$button","forEach","className","startsWith","remove","add","buttonClasses","initMenu","$menu","createMenu","insertAdjacentHTML","toggleTemplate","setupMenuItems","$menuToggle","querySelector","$items","querySelectorAll","addEventListener","event","toggleMenu","handleKeyDown","target","Node","closeMenu","createElement","hidden","alignMenu","appendChild","firstChild","from","$menuItem","$listItem","insertBefore","tagName","setTimeout","buttonText","isOpen","getAttribute","preventDefault","keyboardEvent","detail","focusIndex","openMenu","focusItem","moveFocus","focus","item","currentFocusIndex","$activeElement","activeElement","$menuItems","HTMLAnchorElement","HTMLButtonElement","indexOf","freeze"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}