@ons/design-system 49.2.0 → 51.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 (167) hide show
  1. package/README.md +35 -13
  2. package/components/access-code/_macro.njk +1 -1
  3. package/components/access-code/_macro.spec.js +162 -0
  4. package/components/access-code/uac.spec.js +26 -0
  5. package/components/accordion/_macro.spec.js +224 -0
  6. package/components/accordion/accordion.spec.js +134 -0
  7. package/components/address-input/_macro.njk +1 -1
  8. package/components/address-input/_macro.spec.js +465 -0
  9. package/components/address-input/autosuggest.address.js +5 -4
  10. package/components/address-input/autosuggest.address.setter.js +3 -1
  11. package/components/address-input/autosuggest.address.spec.js +733 -0
  12. package/components/address-output/_macro.njk +6 -6
  13. package/components/address-output/_macro.spec.js +122 -0
  14. package/components/autosuggest/_macro.njk +1 -1
  15. package/components/autosuggest/_macro.spec.js +229 -0
  16. package/components/autosuggest/autosuggest.helpers.js +2 -3
  17. package/components/autosuggest/autosuggest.helpers.spec.js +85 -0
  18. package/components/autosuggest/autosuggest.js +4 -2
  19. package/components/autosuggest/autosuggest.spec.js +625 -0
  20. package/components/autosuggest/autosuggest.ui.js +6 -2
  21. package/components/breadcrumbs/_macro.spec.js +129 -0
  22. package/components/button/_macro.njk +5 -5
  23. package/components/button/_macro.spec.js +446 -0
  24. package/components/button/button.spec.js +290 -0
  25. package/components/call-to-action/_macro.njk +3 -1
  26. package/components/call-to-action/_macro.spec.js +52 -0
  27. package/components/card/_macro.njk +26 -19
  28. package/components/card/_macro.spec.js +261 -0
  29. package/components/char-check-limit/_macro.spec.js +73 -0
  30. package/components/char-check-limit/character-check.spec.js +196 -0
  31. package/components/char-check-limit/character-limit.js +1 -1
  32. package/components/checkboxes/_checkbox-macro.njk +2 -2
  33. package/components/checkboxes/_checkbox-macro.spec.js +419 -0
  34. package/components/checkboxes/_macro.njk +3 -5
  35. package/components/checkboxes/_macro.spec.js +306 -0
  36. package/components/checkboxes/checkboxes.spec.js +208 -0
  37. package/components/code-highlight/_macro.spec.js +56 -0
  38. package/components/code-highlight/code-highlight.spec.js +18 -0
  39. package/components/collapsible/_macro.spec.js +204 -0
  40. package/components/collapsible/collapsible.js +2 -1
  41. package/components/collapsible/collapsible.spec.js +236 -0
  42. package/components/content-pagination/_macro.spec.js +199 -0
  43. package/components/cookies-banner/_macro.njk +1 -1
  44. package/components/cookies-banner/_macro.spec.js +171 -0
  45. package/components/cookies-banner/cookies-banner.spec.js +90 -0
  46. package/components/date-input/_macro.njk +8 -5
  47. package/components/date-input/_macro.spec.js +286 -0
  48. package/components/document-list/_macro.njk +3 -5
  49. package/components/document-list/_macro.spec.js +491 -0
  50. package/components/download-resources/download-resources.spec.js +540 -0
  51. package/components/duration/_macro.njk +7 -6
  52. package/components/duration/_macro.spec.js +251 -0
  53. package/components/error/_macro.spec.js +97 -0
  54. package/components/external-link/_macro.spec.js +60 -0
  55. package/components/feedback/_macro.njk +5 -3
  56. package/components/feedback/_macro.spec.js +122 -0
  57. package/components/field/_macro.njk +2 -2
  58. package/components/field/_macro.spec.js +97 -0
  59. package/components/fieldset/_macro.njk +3 -3
  60. package/components/fieldset/_macro.spec.js +173 -0
  61. package/components/footer/_macro.njk +11 -48
  62. package/components/footer/_macro.spec.js +549 -0
  63. package/components/header/_macro.njk +2 -2
  64. package/components/header/_macro.spec.js +562 -0
  65. package/components/hero/_hero.scss +0 -3
  66. package/components/hero/_macro.njk +4 -4
  67. package/components/hero/_macro.spec.js +224 -0
  68. package/components/icons/_macro.njk +15 -15
  69. package/components/icons/_macro.spec.js +140 -0
  70. package/components/images/_macro.njk +1 -1
  71. package/components/images/_macro.spec.js +121 -0
  72. package/components/input/_input-type.scss +12 -5
  73. package/components/input/_macro.njk +6 -7
  74. package/components/input/_macro.spec.js +658 -0
  75. package/components/label/_macro.spec.js +189 -0
  76. package/components/language-selector/_macro.spec.js +129 -0
  77. package/components/lists/_list.scss +4 -0
  78. package/components/lists/_macro.njk +4 -7
  79. package/components/lists/_macro.spec.js +618 -0
  80. package/components/message/_macro.spec.js +137 -0
  81. package/components/message-list/_macro.njk +7 -7
  82. package/components/message-list/_macro.spec.js +159 -0
  83. package/components/metadata/_macro.spec.js +167 -0
  84. package/components/modal/_macro.njk +6 -6
  85. package/components/modal/_macro.spec.js +87 -0
  86. package/components/modal/modal.js +0 -16
  87. package/components/modal/modal.spec.js +59 -0
  88. package/components/mutually-exclusive/_macro.njk +38 -21
  89. package/components/mutually-exclusive/_macro.spec.js +182 -0
  90. package/components/mutually-exclusive/mutually-exclusive.checkboxes.spec.js +203 -0
  91. package/components/mutually-exclusive/mutually-exclusive.date.spec.js +142 -0
  92. package/components/mutually-exclusive/mutually-exclusive.duration.spec.js +141 -0
  93. package/components/mutually-exclusive/mutually-exclusive.email.spec.js +117 -0
  94. package/components/mutually-exclusive/mutually-exclusive.js +32 -23
  95. package/components/mutually-exclusive/mutually-exclusive.multiple-options.checkboxes.spec.js +213 -0
  96. package/components/mutually-exclusive/mutually-exclusive.number.spec.js +125 -0
  97. package/components/mutually-exclusive/mutually-exclusive.textarea.spec.js +131 -0
  98. package/components/navigation/_macro.njk +6 -6
  99. package/components/navigation/_macro.spec.js +327 -0
  100. package/components/navigation/navigation.dom.js +1 -1
  101. package/components/navigation/navigation.spec.js +232 -0
  102. package/components/pagination/_macro.njk +1 -1
  103. package/components/pagination/_macro.spec.js +411 -0
  104. package/components/panel/_macro.njk +6 -6
  105. package/components/panel/_macro.spec.js +423 -0
  106. package/components/password/_macro.spec.js +137 -0
  107. package/components/password/password.spec.js +40 -0
  108. package/components/phase-banner/_macro.spec.js +73 -0
  109. package/components/promotional-banner/_macro.spec.js +97 -0
  110. package/components/question/_macro.njk +25 -33
  111. package/components/question/_macro.spec.js +309 -0
  112. package/components/quote/_macro.spec.js +81 -0
  113. package/components/radios/_macro.njk +98 -102
  114. package/components/radios/_macro.spec.js +575 -0
  115. package/components/radios/radios.spec.js +180 -0
  116. package/components/related-content/_macro.njk +1 -0
  117. package/components/related-content/_macro.spec.js +142 -0
  118. package/components/relationships/_macro.spec.js +108 -0
  119. package/components/relationships/relationships.spec.js +84 -0
  120. package/components/reply/_macro.njk +2 -2
  121. package/components/reply/_macro.spec.js +69 -0
  122. package/components/reply/reply.spec.js +78 -0
  123. package/components/search/_macro.njk +14 -12
  124. package/components/search/_macro.spec.js +44 -0
  125. package/components/search/_search.scss +7 -7
  126. package/components/section-navigation/_macro.njk +7 -2
  127. package/components/section-navigation/_macro.spec.js +206 -0
  128. package/components/select/_macro.njk +3 -3
  129. package/components/select/_macro.spec.js +203 -0
  130. package/components/select/select.spec.js +56 -0
  131. package/components/share-page/_macro.njk +2 -2
  132. package/components/share-page/_macro.spec.js +110 -0
  133. package/components/skip-to-content/_macro.spec.js +57 -0
  134. package/components/skip-to-content/skip-to-content.spec.js +44 -0
  135. package/components/status/_macro.spec.js +77 -0
  136. package/components/summary/_macro.njk +5 -5
  137. package/components/summary/_macro.spec.js +472 -0
  138. package/components/table/_macro.njk +2 -2
  139. package/components/table/_macro.spec.js +557 -0
  140. package/components/table/table.spec.js +155 -0
  141. package/components/table-of-contents/_macro.njk +35 -35
  142. package/components/table-of-contents/_macro.spec.js +178 -0
  143. package/components/table-of-contents/toc.js +29 -25
  144. package/components/table-of-contents/toc.spec.js +61 -0
  145. package/components/tabs/_macro.njk +1 -1
  146. package/components/tabs/_macro.spec.js +79 -0
  147. package/components/tabs/tabs.spec.js +162 -0
  148. package/components/text-indent/_macro.spec.js +52 -0
  149. package/components/textarea/_macro.njk +7 -5
  150. package/components/textarea/_macro.spec.js +300 -0
  151. package/components/textarea/textarea.spec.js +98 -0
  152. package/components/timeline/_macro.njk +3 -3
  153. package/components/timeline/_macro.spec.js +81 -0
  154. package/components/timeout-modal/_macro.spec.js +68 -0
  155. package/components/timeout-modal/timeout-modal.spec.js +226 -0
  156. package/components/timeout-panel/_macro.njk +0 -1
  157. package/components/timeout-panel/_macro.spec.js +54 -0
  158. package/components/timeout-panel/timeout-panel.dom.js +1 -2
  159. package/components/timeout-panel/timeout-panel.spec.js +161 -0
  160. package/components/upload/_macro.spec.js +75 -0
  161. package/components/video/_macro.spec.js +34 -0
  162. package/css/census.css +1 -1
  163. package/css/main.css +1 -1
  164. package/js/cookies-settings.spec.js +154 -0
  165. package/package.json +10 -23
  166. package/scripts/main.es5.js +1 -1
  167. package/scripts/main.js +2 -2
@@ -0,0 +1,137 @@
1
+ /** @jest-environment jsdom */
2
+
3
+ import * as cheerio from 'cheerio';
4
+
5
+ import axe from '../../tests/helpers/axe';
6
+ import { renderComponent } from '../../tests/helpers/rendering';
7
+
8
+ const EXAMPLE_MESSAGE_MINIMAL = {
9
+ type: 'sent',
10
+ fromLabel: 'From',
11
+ fromValue: 'Example Sender',
12
+ sentLabel: 'Date sent',
13
+ sentValue: 'Tue 4 Jul 2020 at 7:47',
14
+ };
15
+
16
+ const EXAMPLE_MESSAGE = {
17
+ ...EXAMPLE_MESSAGE_MINIMAL,
18
+ unreadLink: 'https://example.com/message/1',
19
+ unreadLinkText: 'Unread message',
20
+ id: 'message1',
21
+ name: 'example-message-1',
22
+ fromId: 'from1',
23
+ sentId: 'sent1',
24
+ unreadLinkId: 'unreadLink1',
25
+ messageID: 'messageBody1',
26
+ };
27
+
28
+ describe('macro: message', () => {
29
+ it('passes jest-axe checks when all parameters are provided', async () => {
30
+ const $ = cheerio.load(renderComponent('message', EXAMPLE_MESSAGE, ['Message content...']));
31
+
32
+ const results = await axe($.html());
33
+ expect(results).toHaveNoViolations();
34
+ });
35
+
36
+ it.each([
37
+ ['sent', 'ons-message--sent'],
38
+ ['received', 'ons-message--received'],
39
+ ])('has appropriate class for provided `type` (%s -> %s)', (type, expectedClass) => {
40
+ const $ = cheerio.load(
41
+ renderComponent(
42
+ 'message',
43
+ {
44
+ ...EXAMPLE_MESSAGE_MINIMAL,
45
+ type,
46
+ },
47
+ ['Message content...'],
48
+ ),
49
+ );
50
+
51
+ expect($('.ons-message').hasClass(expectedClass)).toBe(true);
52
+ });
53
+
54
+ it('has `id` attribute on `.ons-message__metadata` using the provided value', () => {
55
+ const $ = cheerio.load(renderComponent('message', EXAMPLE_MESSAGE, ['Message content...']));
56
+
57
+ expect($('.ons-message__metadata').attr('id')).toBe('message1');
58
+ });
59
+
60
+ it('has the provided `fromLabel`', () => {
61
+ const $ = cheerio.load(renderComponent('message', EXAMPLE_MESSAGE_MINIMAL, ['Message content...']));
62
+
63
+ expect(
64
+ $('.ons-message__sender .ons-message__term')
65
+ .text()
66
+ .trim(),
67
+ ).toBe('From:');
68
+ });
69
+
70
+ it('has the provided `fromValue`', () => {
71
+ const $ = cheerio.load(renderComponent('message', EXAMPLE_MESSAGE_MINIMAL, ['Message content...']));
72
+
73
+ expect(
74
+ $('.ons-message__sender .ons-message__value')
75
+ .text()
76
+ .trim(),
77
+ ).toBe('Example Sender');
78
+ });
79
+
80
+ it('has the provided `fromId`', () => {
81
+ const $ = cheerio.load(renderComponent('message', EXAMPLE_MESSAGE, ['Message content...']));
82
+
83
+ expect($('.ons-message__sender .ons-message__value').attr('id')).toBe('from1');
84
+ });
85
+
86
+ it('has the provided `sentLabel`', () => {
87
+ const $ = cheerio.load(renderComponent('message', EXAMPLE_MESSAGE_MINIMAL, ['Message content...']));
88
+
89
+ expect(
90
+ $('.ons-message__timestamp .ons-message__term')
91
+ .text()
92
+ .trim(),
93
+ ).toBe('Date sent:');
94
+ });
95
+
96
+ it('has the provided `sentValue`', () => {
97
+ const $ = cheerio.load(renderComponent('message', EXAMPLE_MESSAGE_MINIMAL, ['Message content...']));
98
+
99
+ expect(
100
+ $('.ons-message__timestamp .ons-message__value')
101
+ .text()
102
+ .trim(),
103
+ ).toBe('Tue 4 Jul 2020 at 7:47');
104
+ });
105
+
106
+ it('has the provided `sentId`', () => {
107
+ const $ = cheerio.load(renderComponent('message', EXAMPLE_MESSAGE, ['Message content...']));
108
+
109
+ expect($('.ons-message__timestamp .ons-message__value').attr('id')).toBe('sent1');
110
+ });
111
+
112
+ it('has the provided `unreadLink`', () => {
113
+ const $ = cheerio.load(renderComponent('message', EXAMPLE_MESSAGE, ['Message content...']));
114
+
115
+ expect($('.ons-message__unread-link').attr('href')).toBe('https://example.com/message/1');
116
+ });
117
+
118
+ it('has the provided `unreadLinkText`', () => {
119
+ const $ = cheerio.load(renderComponent('message', EXAMPLE_MESSAGE, ['Message content...']));
120
+
121
+ expect(
122
+ $('.ons-message__unread-link')
123
+ .text()
124
+ .trim(),
125
+ ).toBe('Unread message');
126
+ });
127
+
128
+ it('has the message content', () => {
129
+ const $ = cheerio.load(renderComponent('message', EXAMPLE_MESSAGE_MINIMAL, ['Message content...']));
130
+
131
+ expect(
132
+ $('.ons-message__body')
133
+ .text()
134
+ .trim(),
135
+ ).toBe('Message content...');
136
+ });
137
+ });
@@ -4,14 +4,14 @@
4
4
  <li class="ons-message-item" aria-labelledby="{{ message.id }}">
5
5
  <h3 class="ons-message-item__subject" id="{{ message.id }}">
6
6
  <a href="{{ message.url }}" class="ons-u-fs-r--b">{{ message.subject }}</a>
7
- {% if message.unread is defined and message.unread %}<span class="ons-u-fs-s">({{ params.unreadText }})</span>{% endif %}
7
+ {% if message.unread is defined and message.unread %}<span class="ons-message-item__unread ons-u-fs-s">({{ params.unreadText }})</span>{% endif %}
8
8
  </h3>
9
- <dl class="ons-message-item__metadata" aria-label="{{ params.ariaLabelMetaData | default("Message metadata") }}">
10
- <dt class="ons-message-item__metadata-term ons-u-vh">{{ params.fromLabel }}:</dt>
11
- <dd class="ons-message-item__metadata-value ons-u-fs-r--b">{{ message.fromText }}</dd>
12
- <dt class="ons-message-item__metadata-term ons-u-vh">{{ params.dateLabel }}:</dt>
13
- <dd class="ons-message-item__metadata-value ons-u-fs-s">{{ message.dateText }}</dd>
14
- </dl>
9
+ <dl class="ons-message-item__metadata" aria-label="{{ params.ariaLabelMetaData | default("Message metadata") }}">
10
+ <dt class="ons-message-item__metadata-term ons-message-item__metadata-term--from ons-u-vh">{{ params.fromLabel }}:</dt>
11
+ <dd class="ons-message-item__metadata-value ons-message-item__metadata-value--from ons-u-fs-r--b">{{ message.fromText }}</dd>
12
+ <dt class="ons-message-item__metadata-term ons-message-item__metadata-term--date ons-u-vh">{{ params.dateLabel }}:</dt>
13
+ <dd class="ons-message-item__metadata-value ons-message-item__metadata-value--date ons-u-fs-s">{{ message.dateText }}</dd>
14
+ </dl>
15
15
  <div class="ons-message-item__body" aria-label="{{ params.ariaLabelMsg | default("Message text") }}">
16
16
  {{ message.body | safe }}
17
17
  </div>
@@ -0,0 +1,159 @@
1
+ /** @jest-environment jsdom */
2
+
3
+ import * as cheerio from 'cheerio';
4
+
5
+ import axe from '../../tests/helpers/axe';
6
+ import { renderComponent } from '../../tests/helpers/rendering';
7
+
8
+ const EXAMPLE_MESSAGE_LIST_MINIMAL = {
9
+ unreadText: 'New',
10
+ fromLabel: 'From',
11
+ dateLabel: 'Date',
12
+ hiddenReadLabel: 'Read the message',
13
+ messages: [
14
+ {
15
+ id: 'message1',
16
+ unread: true,
17
+ url: 'https://example.com/message/1',
18
+ subject: 'Example message subject',
19
+ fromText: 'Example Sender 1',
20
+ dateText: 'Tue 4 Jul 2020 at 7:47',
21
+ body: 'An example message.',
22
+ },
23
+ {
24
+ id: 'message2',
25
+ url: 'https://example.com/message/2',
26
+ subject: 'Another example message subject',
27
+ fromText: 'Example Sender 2',
28
+ dateText: 'Mon 1 Oct 2019 at 9:52',
29
+ body: 'Another example message.',
30
+ },
31
+ ],
32
+ };
33
+
34
+ const EXAMPLE_MESSAGE_LIST = {
35
+ ...EXAMPLE_MESSAGE_LIST_MINIMAL,
36
+ ariaLabel: 'Message list for ONS Business Surveys',
37
+ ariaLabelMetaData: 'Message information',
38
+ ariaLabelMsg: 'Message preview',
39
+ };
40
+
41
+ describe('macro: message-list', () => {
42
+ it('passes jest-axe checks when all parameters are provided', async () => {
43
+ const $ = cheerio.load(renderComponent('message-list', EXAMPLE_MESSAGE_LIST));
44
+
45
+ const results = await axe($.html());
46
+ expect(results).toHaveNoViolations();
47
+ });
48
+
49
+ it('has `aria-label` attribute on `.ons-message-list` with the correct default value', () => {
50
+ const $ = cheerio.load(renderComponent('message-list', EXAMPLE_MESSAGE_LIST_MINIMAL));
51
+
52
+ expect($('.ons-message-list').attr('aria-label')).toBe('Message List');
53
+ });
54
+
55
+ it('has `aria-label` attribute on `.ons-message-list` using the provided value', () => {
56
+ const $ = cheerio.load(renderComponent('message-list', EXAMPLE_MESSAGE_LIST));
57
+
58
+ expect($('.ons-message-list').attr('aria-label')).toBe('Message list for ONS Business Surveys');
59
+ });
60
+
61
+ it('has `aria-label` attribute on `.ons-message-item__metadata` with the correct default value', () => {
62
+ const $ = cheerio.load(renderComponent('message-list', EXAMPLE_MESSAGE_LIST_MINIMAL));
63
+
64
+ expect($('.ons-message-item__metadata:first').attr('aria-label')).toBe('Message metadata');
65
+ });
66
+
67
+ it('has `aria-label` attribute on `.ons-message-item__metadata` using the provided value', () => {
68
+ const $ = cheerio.load(renderComponent('message-list', EXAMPLE_MESSAGE_LIST));
69
+
70
+ expect($('.ons-message-item__metadata:first').attr('aria-label')).toBe('Message information');
71
+ });
72
+
73
+ it('has `aria-label` attribute on `.ons-message-item__body` with the correct default value', () => {
74
+ const $ = cheerio.load(renderComponent('message-list', EXAMPLE_MESSAGE_LIST_MINIMAL));
75
+
76
+ expect($('.ons-message-item__body:first').attr('aria-label')).toBe('Message text');
77
+ });
78
+
79
+ it('has `aria-label` attribute on `.ons-message-item__body` using the provided value', () => {
80
+ const $ = cheerio.load(renderComponent('message-list', EXAMPLE_MESSAGE_LIST));
81
+
82
+ expect($('.ons-message-item__body:first').attr('aria-label')).toBe('Message preview');
83
+ });
84
+
85
+ it('has `unreadText` for unread messages', () => {
86
+ const $ = cheerio.load(renderComponent('message-list', EXAMPLE_MESSAGE_LIST));
87
+
88
+ expect(
89
+ $('#message1 .ons-message-item__unread')
90
+ .text()
91
+ .trim(),
92
+ ).toBe('(New)');
93
+ });
94
+
95
+ it('has visually hidden label `fromLabel`', () => {
96
+ const $ = cheerio.load(renderComponent('message-list', EXAMPLE_MESSAGE_LIST_MINIMAL));
97
+
98
+ expect(
99
+ $('.ons-message-item__metadata-term--from:first')
100
+ .text()
101
+ .trim(),
102
+ ).toBe('From:');
103
+ });
104
+
105
+ it('has visually hidden label `dateLabel`', () => {
106
+ const $ = cheerio.load(renderComponent('message-list', EXAMPLE_MESSAGE_LIST_MINIMAL));
107
+
108
+ expect(
109
+ $('.ons-message-item__metadata-term--date:first')
110
+ .text()
111
+ .trim(),
112
+ ).toBe('Date:');
113
+ });
114
+
115
+ it('has visually hidden label `hiddenReadLabel`', () => {
116
+ const $ = cheerio.load(renderComponent('message-list', EXAMPLE_MESSAGE_LIST_MINIMAL));
117
+
118
+ expect($('.ons-message-item__link:first').text()).toContain('Read the message: ');
119
+ });
120
+
121
+ it('has message as expected', () => {
122
+ const $ = cheerio.load(renderComponent('message-list', EXAMPLE_MESSAGE_LIST_MINIMAL));
123
+
124
+ const $message2 = $('.ons-message-item:nth-child(2)');
125
+
126
+ expect(
127
+ $message2
128
+ .find('.ons-message-item__subject')
129
+ .text()
130
+ .trim(),
131
+ ).toBe('Another example message subject');
132
+ expect($message2.find('.ons-message-item__subject').attr('id')).toBe('message2');
133
+ expect(
134
+ $message2
135
+ .find('.ons-message-item__metadata-value--from')
136
+ .text()
137
+ .trim(),
138
+ ).toBe('Example Sender 2');
139
+ expect(
140
+ $message2
141
+ .find('.ons-message-item__metadata-value--date')
142
+ .text()
143
+ .trim(),
144
+ ).toBe('Mon 1 Oct 2019 at 9:52');
145
+ expect(
146
+ $message2
147
+ .find('.ons-message-item__body')
148
+ .text()
149
+ .trim(),
150
+ ).toBe('Another example message.');
151
+ expect($message2.find('.ons-message-item__link a').attr('href')).toBe('https://example.com/message/2');
152
+ });
153
+
154
+ it('has `aria-labelledby` attribute on message', () => {
155
+ const $ = cheerio.load(renderComponent('message-list', EXAMPLE_MESSAGE_LIST_MINIMAL));
156
+
157
+ expect($('.ons-message-item:first').attr('aria-labelledby')).toBe('message1');
158
+ });
159
+ });
@@ -0,0 +1,167 @@
1
+ /** @jest-environment jsdom */
2
+
3
+ import * as cheerio from 'cheerio';
4
+
5
+ import axe from '../../tests/helpers/axe';
6
+ import { renderComponent } from '../../tests/helpers/rendering';
7
+
8
+ const EXAMPLE_METADATA_FULL = {
9
+ id: 'example-id',
10
+ classes: 'ons-u-mb-no',
11
+ metadataLabel: 'This is an example of the metadata component',
12
+ termCol: 2,
13
+ descriptionCol: 10,
14
+ itemsList: [
15
+ {
16
+ term: 'Survey:',
17
+ descriptions: [
18
+ {
19
+ id: 'description-1',
20
+ description: 'Bricks & Blocks',
21
+ },
22
+ ],
23
+ },
24
+ {
25
+ term: 'RU Refs:',
26
+ descriptions: [
27
+ {
28
+ id: 'description-2',
29
+ description: '49900000118',
30
+ },
31
+ {
32
+ id: 'description-3',
33
+ description: '49300005832',
34
+ },
35
+ ],
36
+ },
37
+ ],
38
+ };
39
+
40
+ const EXAMPLE_METADATA_MINIMAL = {
41
+ itemsList: [
42
+ {
43
+ term: 'Survey:',
44
+ descriptions: [
45
+ {
46
+ description: 'Bricks & Blocks',
47
+ },
48
+ ],
49
+ },
50
+ {
51
+ term: 'RU Refs:',
52
+ descriptions: [
53
+ {
54
+ description: '49900000118',
55
+ },
56
+ {
57
+ description: '49300005832',
58
+ },
59
+ ],
60
+ },
61
+ ],
62
+ };
63
+
64
+ describe('macro: metadata', () => {
65
+ it('passes jest-axe checks when all parameters are provided', async () => {
66
+ const $ = cheerio.load(renderComponent('metadata', EXAMPLE_METADATA_FULL));
67
+
68
+ const results = await axe($.html());
69
+ expect(results).toHaveNoViolations();
70
+ });
71
+
72
+ it('passes jest-axe checks when minimal parameters are provided', async () => {
73
+ const $ = cheerio.load(renderComponent('metadata', EXAMPLE_METADATA_MINIMAL));
74
+
75
+ const results = await axe($.html());
76
+ expect(results).toHaveNoViolations();
77
+ });
78
+
79
+ it('has the provided `id` attribute', () => {
80
+ const $ = cheerio.load(
81
+ renderComponent('metadata', {
82
+ ...EXAMPLE_METADATA_MINIMAL,
83
+ id: 'example-id',
84
+ }),
85
+ );
86
+
87
+ expect($('#example-id').length).toBe(1);
88
+ });
89
+
90
+ it('has additionally provided style classes', () => {
91
+ const $ = cheerio.load(
92
+ renderComponent('metadata', {
93
+ ...EXAMPLE_METADATA_MINIMAL,
94
+ classes: 'extra-class another-extra-class',
95
+ }),
96
+ );
97
+
98
+ expect($('.ons-metadata').hasClass('extra-class')).toBe(true);
99
+ expect($('.ons-metadata').hasClass('another-extra-class')).toBe(true);
100
+ });
101
+
102
+ it('outputs `title` and `aria-label` attributes when `metadataLabel` is provided', () => {
103
+ const $ = cheerio.load(
104
+ renderComponent('metadata', {
105
+ ...EXAMPLE_METADATA_MINIMAL,
106
+ metadataLabel: 'This is an example of the metadata component',
107
+ }),
108
+ );
109
+
110
+ expect($('.ons-metadata').attr('title')).toBe('This is an example of the metadata component');
111
+ expect($('.ons-metadata').attr('aria-label')).toBe('This is an example of the metadata component');
112
+ });
113
+
114
+ it('outputs list items as expected', () => {
115
+ const $ = cheerio.load(renderComponent('metadata', EXAMPLE_METADATA_FULL));
116
+
117
+ const $listElements = $('.ons-metadata__term, .ons-metadata__value');
118
+
119
+ expect($listElements[0].tagName).toBe('dt');
120
+ expect($($listElements[0]).text()).toBe('Survey:');
121
+
122
+ expect($listElements[1].tagName).toBe('dd');
123
+ expect($($listElements[1]).attr('id')).toBe('description-1');
124
+ expect($($listElements[1]).text()).toBe('Bricks & Blocks');
125
+
126
+ expect($listElements[2].tagName).toBe('dt');
127
+ expect($($listElements[2]).text()).toBe('RU Refs:');
128
+
129
+ expect($listElements[3].tagName).toBe('dd');
130
+ expect($($listElements[3]).attr('id')).toBe('description-2');
131
+ expect($($listElements[3]).text()).toBe('49900000118');
132
+
133
+ expect($listElements[4].tagName).toBe('dd');
134
+ expect($($listElements[4]).attr('id')).toBe('description-3');
135
+ expect($($listElements[4]).text()).toBe('49300005832');
136
+ });
137
+
138
+ it.each([
139
+ [1, 'ons-col-1\\@m'],
140
+ [4, 'ons-col-4\\@m'],
141
+ ])('applies class for the provided `termCol` (%i -> %s)', (termCol, expectedClass) => {
142
+ const $ = cheerio.load(
143
+ renderComponent('metadata', {
144
+ ...EXAMPLE_METADATA_MINIMAL,
145
+ termCol,
146
+ }),
147
+ );
148
+
149
+ const $termElements = $(`.ons-metadata__term.${expectedClass}`);
150
+ expect($termElements.length).toBe(2);
151
+ });
152
+
153
+ it.each([
154
+ [1, 'ons-col-1\\@m'],
155
+ [4, 'ons-col-4\\@m'],
156
+ ])('applies class for the provided `descriptionCol` (%i -> %s)', (descriptionCol, expectedClass) => {
157
+ const $ = cheerio.load(
158
+ renderComponent('metadata', {
159
+ ...EXAMPLE_METADATA_MINIMAL,
160
+ descriptionCol,
161
+ }),
162
+ );
163
+
164
+ const $valueElements = $(`.ons-metadata__value.${expectedClass}`);
165
+ expect($valueElements.length).toBe(3);
166
+ });
167
+ });
@@ -1,19 +1,19 @@
1
1
  {% macro onsModal(params) %}
2
- {% set modalID = params.id | default('dialog') %}
3
- <dialog class="ons-modal ons-js-modal {{ params.classes }}"
4
- id="{{ modalID }}"
2
+ {% set modalId = params.id | default('dialog') %}
3
+ <dialog class="ons-modal ons-js-modal {{ params.classes if params.classes is defined and params.classes else '' }}"
4
+ id="{{ modalId }}"
5
5
  role="dialog"
6
6
  aria-labelledby="ons-modal-title"
7
7
  {% if params.attributes is defined and params.attributes %}{% for attribute, value in (params.attributes.items() if params.attributes is mapping and params.attributes.items else params.attributes) %} {{attribute}}="{{value}}"{% endfor %}{% endif %}
8
- >
8
+ >
9
9
  <div class="ons-modal__content">
10
10
  <h1 id="ons-modal-title" class="ons-modal__title">
11
11
  {{ params.title }}
12
12
  </h1>
13
13
  <div class="ons-modal__body">
14
- {{ (params.body if params else "") | safe }}{{ caller() if caller }}
14
+ {{ (params.body if params.body is defined and params.body else "") | safe }}{{ caller() if caller }}
15
15
  </div>
16
- {% if params.btnText %}
16
+ {% if params.btnText is defined and params.btnText %}
17
17
  {% from "components/button/_macro.njk" import onsButton %}
18
18
  {{ onsButton({
19
19
  "text": params.btnText,
@@ -0,0 +1,87 @@
1
+ /** @jest-environment jsdom */
2
+
3
+ import * as cheerio from 'cheerio';
4
+
5
+ import axe from '../../tests/helpers/axe';
6
+ import { renderComponent, templateFaker } from '../../tests/helpers/rendering';
7
+
8
+ const EXAMPLE_MODAL_BASIC = {
9
+ title: 'Modal title',
10
+ body: 'Modal body text',
11
+ btnText: 'Modal button',
12
+ };
13
+
14
+ describe('macro: modal', () => {
15
+ it('passes jest-axe checks with', async () => {
16
+ const $ = cheerio.load(renderComponent('modal', EXAMPLE_MODAL_BASIC));
17
+
18
+ const results = await axe($.html());
19
+ expect(results).toHaveNoViolations();
20
+ });
21
+
22
+ it('has expected `title`', () => {
23
+ const $ = cheerio.load(renderComponent('modal', EXAMPLE_MODAL_BASIC));
24
+
25
+ const title = $('.ons-modal__title')
26
+ .html()
27
+ .trim();
28
+ expect(title).toBe('Modal title');
29
+ });
30
+
31
+ it('has expected `body`', () => {
32
+ const $ = cheerio.load(renderComponent('modal', EXAMPLE_MODAL_BASIC));
33
+
34
+ const title = $('.ons-modal__body')
35
+ .html()
36
+ .trim();
37
+ expect(title).toBe('Modal body text');
38
+ });
39
+
40
+ it('has the default ID', () => {
41
+ const $ = cheerio.load(renderComponent('modal', EXAMPLE_MODAL_BASIC));
42
+ expect($('#dialog').length).toBe(1);
43
+ });
44
+
45
+ it('has the provided `id`', () => {
46
+ const $ = cheerio.load(renderComponent('modal', { ...EXAMPLE_MODAL_BASIC, id: 'modal-id' }));
47
+ expect($('#modal-id').length).toBe(1);
48
+ });
49
+
50
+ it('has the provided `classes`', () => {
51
+ const $ = cheerio.load(renderComponent('modal', { ...EXAMPLE_MODAL_BASIC, classes: 'modal-class' }));
52
+ expect($('.modal-class').length).toBe(1);
53
+ });
54
+
55
+ it('outputs the expected button', () => {
56
+ const faker = templateFaker();
57
+ const buttonSpy = faker.spy('button');
58
+
59
+ faker.renderComponent('modal', EXAMPLE_MODAL_BASIC);
60
+
61
+ expect(buttonSpy.occurrences[0]).toHaveProperty('text', 'Modal button');
62
+ });
63
+
64
+ it('calls with content', () => {
65
+ const $ = cheerio.load(renderComponent('modal', { EXAMPLE_MODAL_BASIC }, 'Example content...'));
66
+
67
+ const content = $('.ons-modal__body')
68
+ .text()
69
+ .trim();
70
+ expect(content).toBe('Example content...');
71
+ });
72
+
73
+ it('has additionally provided `attributes`', () => {
74
+ const $ = cheerio.load(
75
+ renderComponent('modal', {
76
+ ...EXAMPLE_MODAL_BASIC,
77
+ attributes: {
78
+ a: 123,
79
+ b: 456,
80
+ },
81
+ }),
82
+ );
83
+
84
+ expect($('.ons-modal').attr('a')).toBe('123');
85
+ expect($('.ons-modal').attr('b')).toBe('456');
86
+ });
87
+ });
@@ -52,7 +52,6 @@ export default class Modal {
52
52
  document.querySelector('body').classList.add(ie11Class);
53
53
  }
54
54
 
55
- this.makePageContentInert();
56
55
  this.saveLastFocusedEl();
57
56
 
58
57
  if (event) {
@@ -79,20 +78,6 @@ export default class Modal {
79
78
  }
80
79
  }
81
80
 
82
- makePageContentInert() {
83
- if (document.querySelector('.ons-page')) {
84
- document.querySelector('.ons-page').inert = true;
85
- document.querySelector('.ons-page').setAttribute('aria-hidden', 'true');
86
- }
87
- }
88
-
89
- removeInertFromPageContent() {
90
- if (document.querySelector('.ons-page')) {
91
- document.querySelector('.ons-page').inert = false;
92
- document.querySelector('.ons-page').setAttribute('aria-hidden', 'false');
93
- }
94
- }
95
-
96
81
  isDialogOpen() {
97
82
  return this.component['open'];
98
83
  }
@@ -111,7 +96,6 @@ export default class Modal {
111
96
 
112
97
  this.component.close();
113
98
  this.setFocusOnLastFocusedEl(this.lastFocusedEl);
114
- this.removeInertFromPageContent();
115
99
  }
116
100
  }
117
101
  }