@ons/design-system 50.0.1 → 53.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 (182) hide show
  1. package/README.md +35 -15
  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 +9 -3
  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/_button.scss +75 -33
  23. package/components/button/_macro.njk +6 -6
  24. package/components/button/_macro.spec.js +446 -0
  25. package/components/button/button.spec.js +290 -0
  26. package/components/call-to-action/_macro.njk +3 -1
  27. package/components/call-to-action/_macro.spec.js +52 -0
  28. package/components/card/_macro.njk +26 -19
  29. package/components/card/_macro.spec.js +261 -0
  30. package/components/char-check-limit/_macro.spec.js +73 -0
  31. package/components/char-check-limit/character-check.spec.js +196 -0
  32. package/components/char-check-limit/character-limit.js +1 -1
  33. package/components/checkboxes/_checkbox-macro.spec.js +419 -0
  34. package/components/checkboxes/_macro.njk +1 -3
  35. package/components/checkboxes/_macro.spec.js +306 -0
  36. package/components/checkboxes/checkbox-with-autoselect.js +2 -1
  37. package/components/checkboxes/checkboxes.spec.js +208 -0
  38. package/components/code-highlight/_macro.spec.js +56 -0
  39. package/components/code-highlight/code-highlight.spec.js +18 -0
  40. package/components/collapsible/_macro.spec.js +204 -0
  41. package/components/collapsible/collapsible.js +2 -1
  42. package/components/collapsible/collapsible.spec.js +236 -0
  43. package/components/content-pagination/_macro.spec.js +199 -0
  44. package/components/cookies-banner/_macro.njk +1 -1
  45. package/components/cookies-banner/_macro.spec.js +171 -0
  46. package/components/cookies-banner/cookies-banner.spec.js +90 -0
  47. package/components/date-input/_macro.njk +6 -3
  48. package/components/date-input/_macro.spec.js +286 -0
  49. package/components/document-list/_macro.njk +3 -5
  50. package/components/document-list/_macro.spec.js +491 -0
  51. package/components/download-resources/download-resources.spec.js +540 -0
  52. package/components/duration/_macro.njk +7 -6
  53. package/components/duration/_macro.spec.js +251 -0
  54. package/components/error/_macro.spec.js +97 -0
  55. package/components/external-link/_macro.njk +5 -2
  56. package/components/external-link/_macro.spec.js +77 -0
  57. package/components/feedback/_macro.njk +5 -3
  58. package/components/feedback/_macro.spec.js +122 -0
  59. package/components/field/_macro.njk +2 -2
  60. package/components/field/_macro.spec.js +97 -0
  61. package/components/fieldset/_macro.njk +3 -3
  62. package/components/fieldset/_macro.spec.js +173 -0
  63. package/components/footer/_footer.scss +19 -4
  64. package/components/footer/_macro.njk +106 -137
  65. package/components/footer/_macro.spec.js +678 -0
  66. package/components/header/_header.scss +65 -46
  67. package/components/header/_macro.njk +173 -121
  68. package/components/header/_macro.spec.js +618 -0
  69. package/components/hero/_hero.scss +30 -143
  70. package/components/hero/_macro.njk +12 -23
  71. package/components/hero/_macro.spec.js +218 -0
  72. package/components/icons/_macro.njk +258 -30
  73. package/components/icons/_macro.spec.js +140 -0
  74. package/components/images/_macro.njk +1 -1
  75. package/components/images/_macro.spec.js +121 -0
  76. package/components/input/_input-type.scss +12 -5
  77. package/components/input/_input.scss +8 -0
  78. package/components/input/_macro.njk +4 -5
  79. package/components/input/_macro.spec.js +658 -0
  80. package/components/label/_macro.spec.js +189 -0
  81. package/components/language-selector/_macro.njk +1 -1
  82. package/components/language-selector/_macro.spec.js +137 -0
  83. package/components/lists/_list.scss +4 -0
  84. package/components/lists/_macro.njk +4 -7
  85. package/components/lists/_macro.spec.js +618 -0
  86. package/components/message/_macro.spec.js +137 -0
  87. package/components/message-list/_macro.njk +7 -7
  88. package/components/message-list/_macro.spec.js +159 -0
  89. package/components/metadata/_macro.spec.js +167 -0
  90. package/components/modal/_macro.njk +6 -6
  91. package/components/modal/_macro.spec.js +87 -0
  92. package/components/modal/modal.spec.js +59 -0
  93. package/components/mutually-exclusive/_macro.njk +2 -2
  94. package/components/mutually-exclusive/_macro.spec.js +184 -0
  95. package/components/mutually-exclusive/mutually-exclusive.checkboxes.spec.js +203 -0
  96. package/components/mutually-exclusive/mutually-exclusive.date.spec.js +142 -0
  97. package/components/mutually-exclusive/mutually-exclusive.duration.spec.js +141 -0
  98. package/components/mutually-exclusive/mutually-exclusive.email.spec.js +117 -0
  99. package/components/mutually-exclusive/mutually-exclusive.multiple-options.checkboxes.spec.js +213 -0
  100. package/components/mutually-exclusive/mutually-exclusive.number.spec.js +125 -0
  101. package/components/mutually-exclusive/mutually-exclusive.textarea.spec.js +131 -0
  102. package/components/navigation/_macro.njk +45 -38
  103. package/components/navigation/_macro.spec.js +329 -0
  104. package/components/navigation/_navigation.scss +20 -4
  105. package/components/navigation/navigation.dom.js +1 -1
  106. package/components/navigation/navigation.spec.js +232 -0
  107. package/components/pagination/_macro.njk +1 -1
  108. package/components/pagination/_macro.spec.js +411 -0
  109. package/components/panel/_macro.njk +6 -6
  110. package/components/panel/_macro.spec.js +423 -0
  111. package/components/password/_macro.spec.js +137 -0
  112. package/components/password/password.spec.js +40 -0
  113. package/components/phase-banner/_macro.spec.js +73 -0
  114. package/components/promotional-banner/_macro.spec.js +97 -0
  115. package/components/question/_macro.njk +16 -22
  116. package/components/question/_macro.spec.js +309 -0
  117. package/components/quote/_macro.spec.js +81 -0
  118. package/components/radios/_macro.njk +3 -6
  119. package/components/radios/_macro.spec.js +575 -0
  120. package/components/radios/radios.spec.js +180 -0
  121. package/components/related-content/_macro.njk +14 -21
  122. package/components/related-content/_macro.spec.js +133 -0
  123. package/components/related-content/_section-macro.njk +10 -0
  124. package/components/related-content/_section-macro.spec.js +43 -0
  125. package/components/relationships/_macro.spec.js +108 -0
  126. package/components/relationships/relationships.spec.js +84 -0
  127. package/components/reply/_macro.njk +2 -2
  128. package/components/reply/_macro.spec.js +69 -0
  129. package/components/reply/reply.spec.js +78 -0
  130. package/components/search/_macro.njk +14 -12
  131. package/components/search/_macro.spec.js +44 -0
  132. package/components/search/_search.scss +7 -7
  133. package/components/section-navigation/_macro.njk +7 -2
  134. package/components/section-navigation/_macro.spec.js +206 -0
  135. package/components/select/_macro.njk +3 -3
  136. package/components/select/_macro.spec.js +203 -0
  137. package/components/select/select.spec.js +56 -0
  138. package/components/share-page/_macro.njk +6 -4
  139. package/components/share-page/_macro.spec.js +110 -0
  140. package/components/skip-to-content/_macro.spec.js +57 -0
  141. package/components/skip-to-content/skip-to-content.spec.js +44 -0
  142. package/components/status/_macro.spec.js +77 -0
  143. package/components/summary/_macro.njk +5 -5
  144. package/components/summary/_macro.spec.js +472 -0
  145. package/components/table/_macro.njk +2 -2
  146. package/components/table/_macro.spec.js +557 -0
  147. package/components/table/table.spec.js +155 -0
  148. package/components/table-of-contents/_macro.njk +35 -35
  149. package/components/table-of-contents/_macro.spec.js +178 -0
  150. package/components/table-of-contents/toc.js +29 -25
  151. package/components/table-of-contents/toc.spec.js +61 -0
  152. package/components/tabs/_macro.njk +1 -1
  153. package/components/tabs/_macro.spec.js +79 -0
  154. package/components/tabs/tabs.spec.js +162 -0
  155. package/components/text-indent/_macro.spec.js +52 -0
  156. package/components/textarea/_macro.njk +5 -3
  157. package/components/textarea/_macro.spec.js +300 -0
  158. package/components/textarea/textarea.spec.js +98 -0
  159. package/components/timeline/_macro.njk +3 -3
  160. package/components/timeline/_macro.spec.js +81 -0
  161. package/components/timeout-modal/_macro.spec.js +68 -0
  162. package/components/timeout-modal/timeout-modal.spec.js +226 -0
  163. package/components/timeout-panel/_macro.njk +0 -1
  164. package/components/timeout-panel/_macro.spec.js +54 -0
  165. package/components/timeout-panel/timeout-panel.dom.js +1 -2
  166. package/components/timeout-panel/timeout-panel.spec.js +161 -0
  167. package/components/upload/_macro.spec.js +75 -0
  168. package/components/video/_macro.spec.js +34 -0
  169. package/css/census.css +3 -1
  170. package/css/ids.css +2 -0
  171. package/css/main.css +1 -1
  172. package/img/dummy-brand-logo.svg +1 -0
  173. package/js/cookies-settings.spec.js +154 -0
  174. package/layout/_template.njk +7 -4
  175. package/package.json +10 -23
  176. package/scripts/main.es5.js +2 -2
  177. package/scripts/main.js +1 -1
  178. package/scss/ids.scss +2 -0
  179. package/scss/settings/_census.scss +141 -0
  180. package/scss/settings/_ids.scss +48 -0
  181. package/scss/utilities/_margin.scss +1 -0
  182. package/scss/vars/_colors.scss +5 -2
@@ -0,0 +1,203 @@
1
+ /** @jest-environment jsdom */
2
+
3
+ import * as cheerio from 'cheerio';
4
+
5
+ import axe from '../../tests/helpers/axe';
6
+ import { mapAll } from '../../tests/helpers/cheerio';
7
+ import { renderComponent, templateFaker } from '../../tests/helpers/rendering';
8
+
9
+ const EXAMPLE_SELECT_MINIMAL = {
10
+ id: 'example-select',
11
+ name: 'example-select-name',
12
+ label: {
13
+ text: 'Label text',
14
+ description: 'Description text',
15
+ classes: 'extra-label-class',
16
+ },
17
+ options: [
18
+ {
19
+ text: 'First option',
20
+ value: 1,
21
+ },
22
+ {
23
+ id: 'second-option',
24
+ text: 'Second option',
25
+ value: 2,
26
+ selected: true,
27
+ },
28
+ {
29
+ text: 'Disabled option',
30
+ value: 3,
31
+ disabled: true,
32
+ },
33
+ ],
34
+ };
35
+
36
+ const EXAMPLE_SELECT = {
37
+ ...EXAMPLE_SELECT_MINIMAL,
38
+ fieldId: 'example-select-field',
39
+ fieldClasses: 'extra-field-class',
40
+ legendClasses: 'extra-legend-class',
41
+ dontWrap: true,
42
+ };
43
+
44
+ const EXAMPLE_SELECT_WITH_ERROR = {
45
+ ...EXAMPLE_SELECT,
46
+ error: {
47
+ id: 'example-error',
48
+ text: 'Error text...',
49
+ },
50
+ };
51
+
52
+ describe('macro: select', () => {
53
+ it('passes jest-axe checks', async () => {
54
+ const $ = cheerio.load(renderComponent('select', EXAMPLE_SELECT));
55
+
56
+ const results = await axe($.html());
57
+ expect(results).toHaveNoViolations();
58
+ });
59
+
60
+ it('passes jest-axe checks when error is shown', async () => {
61
+ const $ = cheerio.load(renderComponent('select', EXAMPLE_SELECT_WITH_ERROR));
62
+
63
+ const results = await axe($.html());
64
+ expect(results).toHaveNoViolations();
65
+ });
66
+
67
+ it('provides expected parameters to the inner `field` component', () => {
68
+ const faker = templateFaker();
69
+ const fieldSpy = faker.spy('field');
70
+
71
+ cheerio.load(faker.renderComponent('select', EXAMPLE_SELECT));
72
+
73
+ expect(fieldSpy.occurrences[0]).toEqual({
74
+ id: 'example-select-field',
75
+ classes: 'extra-field-class',
76
+ legendClasses: 'extra-legend-class',
77
+ dontWrap: true,
78
+ error: undefined,
79
+ });
80
+ });
81
+
82
+ it('provides expected parameters to the inner `field` component when there is an error', () => {
83
+ const faker = templateFaker();
84
+ const fieldSpy = faker.spy('field');
85
+
86
+ cheerio.load(faker.renderComponent('select', EXAMPLE_SELECT_WITH_ERROR));
87
+
88
+ expect(fieldSpy.occurrences[0]).toEqual({
89
+ id: 'example-select-field',
90
+ classes: 'extra-field-class',
91
+ legendClasses: 'extra-legend-class',
92
+ dontWrap: true,
93
+ error: {
94
+ id: 'example-error',
95
+ text: 'Error text...',
96
+ },
97
+ });
98
+ });
99
+
100
+ it('provides expected parameters to the inner `label` component', () => {
101
+ const faker = templateFaker();
102
+ const labelSpy = faker.spy('label');
103
+
104
+ cheerio.load(faker.renderComponent('select', EXAMPLE_SELECT));
105
+
106
+ expect(labelSpy.occurrences[0]).toEqual({
107
+ for: 'example-select',
108
+ text: 'Label text',
109
+ description: 'Description text',
110
+ classes: 'extra-label-class',
111
+ });
112
+ });
113
+
114
+ describe('select element', () => {
115
+ it('has the provided `id` attribute', () => {
116
+ const $ = cheerio.load(renderComponent('select', EXAMPLE_SELECT));
117
+
118
+ expect($('select').attr('id')).toBe('example-select');
119
+ });
120
+
121
+ it('has the provided `name` attribute', () => {
122
+ const $ = cheerio.load(renderComponent('select', EXAMPLE_SELECT));
123
+
124
+ expect($('select').attr('name')).toBe('example-select-name');
125
+ });
126
+
127
+ it('has additionally provided style classes', () => {
128
+ const $ = cheerio.load(
129
+ renderComponent('select', {
130
+ ...EXAMPLE_SELECT,
131
+ classes: 'extra-class another-extra-class',
132
+ }),
133
+ );
134
+
135
+ expect($('select').hasClass('extra-class')).toBe(true);
136
+ expect($('select').hasClass('another-extra-class')).toBe(true);
137
+ });
138
+
139
+ it('has additionally provided `attributes`', () => {
140
+ const $ = cheerio.load(
141
+ renderComponent('select', {
142
+ ...EXAMPLE_SELECT,
143
+ attributes: {
144
+ a: 123,
145
+ b: 456,
146
+ },
147
+ }),
148
+ );
149
+
150
+ expect($('select').attr('a')).toBe('123');
151
+ expect($('select').attr('b')).toBe('456');
152
+ });
153
+
154
+ describe('option element', () => {
155
+ it('has expected text', () => {
156
+ const $ = cheerio.load(renderComponent('select', EXAMPLE_SELECT));
157
+
158
+ const values = mapAll($('select > option'), node => node.text().trim());
159
+ expect(values).toEqual(['First option', 'Second option', 'Disabled option']);
160
+ });
161
+
162
+ it('has a provided `id` attribute', () => {
163
+ const $ = cheerio.load(renderComponent('select', EXAMPLE_SELECT));
164
+
165
+ const values = mapAll($('select > option'), node => node.attr('id'));
166
+ expect(values).toEqual([undefined, 'second-option', undefined]);
167
+ });
168
+
169
+ it('marks the correct option as selected', () => {
170
+ const $ = cheerio.load(renderComponent('select', EXAMPLE_SELECT));
171
+
172
+ const values = mapAll($('select > option'), node => node.attr('selected'));
173
+ expect(values).toEqual([undefined, 'selected', undefined]);
174
+ });
175
+
176
+ it('marks the correct option as disabled', () => {
177
+ const $ = cheerio.load(renderComponent('select', EXAMPLE_SELECT));
178
+
179
+ const values = mapAll($('select > option'), node => node.attr('disabled'));
180
+ expect(values).toEqual([undefined, undefined, 'disabled']);
181
+ });
182
+
183
+ it('has a provided `value` attribute', () => {
184
+ const $ = cheerio.load(renderComponent('select', EXAMPLE_SELECT));
185
+
186
+ const values = mapAll($('select > option'), node => node.attr('value'));
187
+ expect(values).toEqual(['1', '2', '3']);
188
+ });
189
+
190
+ it('uses option text as a default `value` attribute', () => {
191
+ const $ = cheerio.load(
192
+ renderComponent('select', {
193
+ ...EXAMPLE_SELECT,
194
+ options: [{ text: 'First option' }, { text: 'Second option' }],
195
+ }),
196
+ );
197
+
198
+ const values = mapAll($('select > option'), node => node.attr('value'));
199
+ expect(values).toEqual(['First option', 'Second option']);
200
+ });
201
+ });
202
+ });
203
+ });
@@ -0,0 +1,56 @@
1
+ import { renderComponent, setTestPage } from '../../tests/helpers/rendering';
2
+
3
+ const EXAMPLE_LANGUAGE_FILTER_PAGE = `
4
+ <div class="ons-js-language-filter">
5
+ ${renderComponent('select', {
6
+ classes: 'ons-js-language-filter__select',
7
+ id: 'language-filter-select',
8
+ options: [
9
+ {
10
+ text: 'Native language',
11
+ value: 'language-native',
12
+ },
13
+ {
14
+ text: 'English',
15
+ value: 'language-english',
16
+ },
17
+ ],
18
+ })}
19
+ <div class="ons-js-language-filter__content" id="language-native"></div>
20
+ <div class="ons-js-language-filter__content ons-u-hidden" id="language-english"></div>
21
+ </div>
22
+ `;
23
+
24
+ describe('script: select', () => {
25
+ beforeEach(async () => {
26
+ await setTestPage('/test', EXAMPLE_LANGUAGE_FILTER_PAGE);
27
+ });
28
+
29
+ describe('language filter page with multiple views', () => {
30
+ it('shows first view by default', async () => {
31
+ const isFirstHidden = await page.$eval('#language-native', node => node.classList.contains('ons-u-hidden'));
32
+ expect(isFirstHidden).toBe(false);
33
+ const isSecondHidden = await page.$eval('#language-english', node => node.classList.contains('ons-u-hidden'));
34
+ expect(isSecondHidden).toBe(true);
35
+ });
36
+
37
+ it('shows second view when selection is changed to the second item', async () => {
38
+ await page.select('#language-filter-select', 'language-english');
39
+
40
+ const isFirstHidden = await page.$eval('#language-native', node => node.classList.contains('ons-u-hidden'));
41
+ expect(isFirstHidden).toBe(true);
42
+ const isSecondHidden = await page.$eval('#language-english', node => node.classList.contains('ons-u-hidden'));
43
+ expect(isSecondHidden).toBe(false);
44
+ });
45
+
46
+ it('shows first view when selection is changed back to the first item', async () => {
47
+ await page.select('#language-filter-select', 'language-english');
48
+ await page.select('#language-filter-select', 'language-native');
49
+
50
+ const isFirstHidden = await page.$eval('#language-native', node => node.classList.contains('ons-u-hidden'));
51
+ expect(isFirstHidden).toBe(false);
52
+ const isSecondHidden = await page.$eval('#language-english', node => node.classList.contains('ons-u-hidden'));
53
+ expect(isSecondHidden).toBe(true);
54
+ });
55
+ });
56
+ });
@@ -1,14 +1,16 @@
1
1
  {% macro onsSharePage(params) %}
2
2
  {% from "components/lists/_macro.njk" import onsList %}
3
3
 
4
- {% set titleTag = params.titleTag | default("h2") %}
5
- <{{ titleTag }} class="ons-u-fs-r--b ons-u-mb-xs">{{ params.title }}</{{ titleTag }}>
4
+ {% if params.title %}
5
+ {% set titleTag = params.titleTag | default("h2") %}
6
+ <{{ titleTag }} class="ons-u-fs-r--b ons-u-mb-xs">{{ params.title }}</{{ titleTag }}>
7
+ {% endif %}
6
8
 
7
9
  {% set list = [] %}
8
10
  {% if params.facebook is defined and params.facebook and params.facebook == true %}
9
11
  {% set facebook =
10
12
  {
11
- "url": 'https://www.facebook.com/sharer/sharer.php?u=' ~ params.pageURL,
13
+ "url": 'https://www.facebook.com/sharer/sharer.php?u=' ~ params.pageURL|urlencode,
12
14
  "text": 'Facebook',
13
15
  "iconType": 'facebook',
14
16
  "rel": 'noreferrer external',
@@ -21,7 +23,7 @@
21
23
  {% if params.twitter is defined and params.twitter and params.twitter == true %}
22
24
  {% set twitter =
23
25
  {
24
- "url": 'https://twitter.com/intent/tweet?original_referer&text=' ~ params.pageTitle ~ '&url=' ~ params.pageURL,
26
+ "url": 'https://twitter.com/intent/tweet?original_referer&text=' ~ params.pageTitle|urlencode ~ '&url=' ~ params.pageURL|urlencode,
25
27
  "text": 'Twitter',
26
28
  "iconType": 'twitter',
27
29
  "rel": 'noreferrer external',
@@ -0,0 +1,110 @@
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_SHARE_PAGE = {
9
+ title: 'Share page',
10
+ pageTitle: 'An example page',
11
+ pageURL: 'https://example.com/an-example-page',
12
+ facebook: true,
13
+ twitter: true,
14
+ };
15
+
16
+ describe('macro: share-page', () => {
17
+ it('passes jest-axe checks with', async () => {
18
+ const $ = cheerio.load(renderComponent('share-page', EXAMPLE_SHARE_PAGE));
19
+
20
+ const results = await axe($.html());
21
+ expect(results).toHaveNoViolations();
22
+ });
23
+
24
+ it('wraps title in <h2> element by default', () => {
25
+ const $ = cheerio.load(renderComponent('share-page', EXAMPLE_SHARE_PAGE));
26
+
27
+ expect(
28
+ $('h2')
29
+ .text()
30
+ .trim(),
31
+ ).toBe('Share page');
32
+ });
33
+
34
+ it('wraps title in custom element when `titleTag` is provided', () => {
35
+ const $ = cheerio.load(
36
+ renderComponent('share-page', {
37
+ ...EXAMPLE_SHARE_PAGE,
38
+ titleTag: 'h4',
39
+ }),
40
+ );
41
+
42
+ expect(
43
+ $('h4')
44
+ .text()
45
+ .trim(),
46
+ ).toBe('Share page');
47
+ });
48
+
49
+ it('uses the provided icon size', () => {
50
+ const faker = templateFaker();
51
+ const listsSpy = faker.spy('lists');
52
+
53
+ faker.renderComponent('share-page', {
54
+ ...EXAMPLE_SHARE_PAGE,
55
+ iconSize: 'xl',
56
+ });
57
+
58
+ expect(listsSpy.occurrences[0].iconSize).toBe('xl');
59
+ });
60
+
61
+ describe('Share on Twitter', () => {
62
+ it('has a link with the expected url', () => {
63
+ const faker = templateFaker();
64
+ const listsSpy = faker.spy('lists');
65
+
66
+ faker.renderComponent('share-page', EXAMPLE_SHARE_PAGE);
67
+
68
+ const twitterItem = listsSpy.occurrences[0].itemsList.find(item => item.text === 'Twitter');
69
+ expect(twitterItem.url).toBe(
70
+ 'https://twitter.com/intent/tweet?original_referer&text=An%20example%20page&url=https%3A%2F%2Fexample.com%2Fan-example-page',
71
+ );
72
+ });
73
+
74
+ it('has a link which opens in a new tab', () => {
75
+ const faker = templateFaker();
76
+ const listsSpy = faker.spy('lists');
77
+
78
+ faker.renderComponent('share-page', EXAMPLE_SHARE_PAGE);
79
+
80
+ const twitterItem = listsSpy.occurrences[0].itemsList.find(item => item.text === 'Twitter');
81
+ expect(twitterItem.rel).toContain('noreferrer');
82
+ expect(twitterItem.rel).toContain('external');
83
+ expect(twitterItem.target).toBe('_blank');
84
+ });
85
+ });
86
+
87
+ describe('Share on Facebook', () => {
88
+ it('has a link with the expected url', () => {
89
+ const faker = templateFaker();
90
+ const listsSpy = faker.spy('lists');
91
+
92
+ faker.renderComponent('share-page', EXAMPLE_SHARE_PAGE);
93
+
94
+ const facebookItem = listsSpy.occurrences[0].itemsList.find(item => item.text === 'Facebook');
95
+ expect(facebookItem.url).toBe('https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fexample.com%2Fan-example-page');
96
+ });
97
+
98
+ it('has a link which opens in a new tab', () => {
99
+ const faker = templateFaker();
100
+ const listsSpy = faker.spy('lists');
101
+
102
+ faker.renderComponent('share-page', EXAMPLE_SHARE_PAGE);
103
+
104
+ const facebookItem = listsSpy.occurrences[0].itemsList.find(item => item.text === 'Facebook');
105
+ expect(facebookItem.rel).toContain('noreferrer');
106
+ expect(facebookItem.rel).toContain('external');
107
+ expect(facebookItem.target).toBe('_blank');
108
+ });
109
+ });
110
+ });
@@ -0,0 +1,57 @@
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
+ describe('macro: skip-to-content', () => {
9
+ it('passes jest-axe checks', async () => {
10
+ const $ = cheerio.load(
11
+ renderComponent('skip-to-content', {
12
+ url: '#example-anchor',
13
+ text: 'Skip to the content',
14
+ }),
15
+ );
16
+
17
+ const results = await axe($.html());
18
+ expect(results).toHaveNoViolations();
19
+ });
20
+
21
+ it('has a hyperlink element', async () => {
22
+ const $ = cheerio.load(
23
+ renderComponent('skip-to-content', {
24
+ url: '#example-anchor',
25
+ text: 'Skip to the content',
26
+ }),
27
+ );
28
+
29
+ expect($('.ons-skip-link')[0].tagName).toBe('a');
30
+ });
31
+
32
+ it('has skip link with the provided `url`', async () => {
33
+ const $ = cheerio.load(
34
+ renderComponent('skip-to-content', {
35
+ url: '#example-anchor',
36
+ text: 'Skip to the content',
37
+ }),
38
+ );
39
+
40
+ expect($('.ons-skip-link').attr('href')).toBe('#example-anchor');
41
+ });
42
+
43
+ it('has skip link with the provided `text`', async () => {
44
+ const $ = cheerio.load(
45
+ renderComponent('skip-to-content', {
46
+ url: '#example-anchor',
47
+ text: 'Skip to the content',
48
+ }),
49
+ );
50
+
51
+ expect(
52
+ $('.ons-skip-link')
53
+ .text()
54
+ .trim(),
55
+ ).toBe('Skip to the content');
56
+ });
57
+ });
@@ -0,0 +1,44 @@
1
+ import { setTestPage } from '../../tests/helpers/rendering';
2
+
3
+ const EXAMPLE_SKIP_TO_LINK_TEMPLATE = `
4
+ {% from "components/skip-to-content/_macro.njk" import onsSkipToContent %}
5
+ {{
6
+ onsSkipToContent({
7
+ "url": "#target-element",
8
+ "text": "Skip to content"
9
+ })
10
+ }}
11
+ <input id="target-element" type="text" style="outline: solid 1px black;" />
12
+ `;
13
+
14
+ describe('script: skip-to-content', () => {
15
+ it('sets `tabIndex` of target element to -1', async () => {
16
+ await setTestPage('/test', EXAMPLE_SKIP_TO_LINK_TEMPLATE);
17
+
18
+ await page.focus('.ons-skip-link');
19
+ await page.keyboard.press('Enter');
20
+
21
+ const targetTabIndex = await page.$eval('#target-element', el => el.tabIndex);
22
+ expect(targetTabIndex).toBe(-1);
23
+ });
24
+
25
+ it('removes outline from target element on navigate', async () => {
26
+ await setTestPage('/test', EXAMPLE_SKIP_TO_LINK_TEMPLATE);
27
+
28
+ await page.focus('.ons-skip-link');
29
+ await page.keyboard.press('Enter');
30
+
31
+ const targetOutline = await page.$eval('#target-element', el => el.style.outline);
32
+ expect(targetOutline).toBe('none');
33
+ });
34
+
35
+ it('focuses target element on navigate', async () => {
36
+ await setTestPage('/test', EXAMPLE_SKIP_TO_LINK_TEMPLATE);
37
+
38
+ await page.focus('.ons-skip-link');
39
+ await page.keyboard.press('Enter');
40
+
41
+ const focusedElementId = await page.evaluate(() => document.activeElement.id);
42
+ expect(focusedElementId).toBe('target-element');
43
+ });
44
+ });
@@ -0,0 +1,77 @@
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
+ describe('macro: status', () => {
9
+ it('passes jest-axe checks', async () => {
10
+ const $ = cheerio.load(
11
+ renderComponent('status', {
12
+ type: 'success',
13
+ label: 'Example status message',
14
+ size: 'small',
15
+ }),
16
+ );
17
+
18
+ const results = await axe($.html());
19
+ expect(results).toHaveNoViolations();
20
+ });
21
+
22
+ it('has the default type "info" when `type` is not provided', () => {
23
+ const $ = cheerio.load(
24
+ renderComponent('status', {
25
+ label: 'Example status message',
26
+ }),
27
+ );
28
+
29
+ expect($('.ons-status').hasClass('ons-status--info')).toBe(true);
30
+ });
31
+
32
+ it('has the provided `type`', () => {
33
+ const $ = cheerio.load(
34
+ renderComponent('status', {
35
+ type: 'success',
36
+ label: 'Example status message',
37
+ }),
38
+ );
39
+
40
+ expect($('.ons-status').hasClass('ons-status--success')).toBe(true);
41
+ });
42
+
43
+ it('does not have the `ons-status--small` modifier by default', () => {
44
+ const $ = cheerio.load(
45
+ renderComponent('status', {
46
+ label: 'Example status message',
47
+ }),
48
+ );
49
+
50
+ expect($('.ons-status').hasClass('ons-status--small')).not.toBe(true);
51
+ });
52
+
53
+ it('has the `ons-status--small` when provided', () => {
54
+ const $ = cheerio.load(
55
+ renderComponent('status', {
56
+ label: 'Example status message',
57
+ size: 'small',
58
+ }),
59
+ );
60
+
61
+ expect($('.ons-status').hasClass('ons-status--small')).toBe(true);
62
+ });
63
+
64
+ it('has the provided `label`', () => {
65
+ const $ = cheerio.load(
66
+ renderComponent('status', {
67
+ label: 'Example status message',
68
+ }),
69
+ );
70
+
71
+ expect(
72
+ $('.ons-status')
73
+ .text()
74
+ .trim(),
75
+ ).toBe('Example status message');
76
+ });
77
+ });
@@ -59,7 +59,7 @@
59
59
  </span>
60
60
  {% endif %}
61
61
 
62
- <div class="ons-summary__item--text{{ ' ons-summary__item-title--text' if rowItem.iconType else "" }}">{{ rowItem.rowTitle | default(row.rowTitle) | safe }} {{ hasIcons }}</div>
62
+ <div class="ons-summary__item--text{{ ' ons-summary__item-title--text' if rowItem.iconType else "" }}">{{ rowItem.rowTitle | default(row.rowTitle) | safe }}</div>
63
63
 
64
64
  {# Render section status for mobile if is hub #}
65
65
  {% if params.hub is defined and params.hub and rowItem.valueList is defined and rowItem.valueList %}
@@ -73,7 +73,7 @@
73
73
  {% if rowItem.attributes is defined and rowItem.attributes %}{% for attribute, value in (rowItem.attributes.items() if rowItem.attributes is mapping and rowItem.attributes.items else rowItem.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %}
74
74
  >
75
75
  {% if rowItem.valueList | length == 1 %}
76
- {{ rowItem.valueList[0].text | safe }}
76
+ <span class="ons-summary__text">{{ rowItem.valueList[0].text | safe }}</span>
77
77
  {% if rowItem.valueList[0].other is defined and rowItem.valueList[0].other or rowItem.valueList[0].other == 0 %}
78
78
  <ul class="ons-u-mb-no">
79
79
  <li>{{ rowItem.valueList[0].other | safe }}</li>
@@ -83,7 +83,7 @@
83
83
  <ul class="ons-u-mb-no">
84
84
  {% for value in (rowItem.valueList if rowItem.valueList is iterable else rowItem.valueList.items()) %}
85
85
  <li>
86
- {{ value.text | safe }}
86
+ <span class="ons-summary__text">{{ value.text | safe }}</span>
87
87
  {% if value.other is defined and value.other or value.other == 0 %}
88
88
  <ul class="ons-u-mb-no">
89
89
  <li>{{ value.other | safe }}</li>
@@ -114,11 +114,11 @@
114
114
  {% endfor %}
115
115
  </table>
116
116
  {% elif group.placeholderText is defined and group.placeholderText %}
117
- {{ group.placeholderText }}
117
+ <span class="ons-summary__placeholder">{{ group.placeholderText }}</span>
118
118
  {% endif %}
119
119
 
120
120
  {% if group.summaryLink is defined and group.summaryLink %}
121
- <div class="{% if group.placeholderText is defined and group.placeholderText or group.rows is defined and group.rows %}ons-u-pt-s{% endif %}{% if group.placeholderText is not defined and group.rows is defined and group.rows | length > 1 %} ons-u-bt{% endif %}">
121
+ <div class="ons-summary__link{% if group.placeholderText is defined and group.placeholderText or group.rows is defined and group.rows %} ons-u-pt-s{% endif %}{% if group.placeholderText is not defined and group.rows is defined and group.rows | length > 1 %} ons-u-bt{% endif %}">
122
122
  <a {% if group.summaryLink.attributes is defined and group.summaryLink.attributes %}{% for attribute, value in (group.summaryLink.attributes.items() if group.summaryLink.attributes is mapping and group.summaryLink.attributes.items else group.summaryLink.attributes) %}{{attribute}}="{{value}}" {% endfor %}{% endif %} href="{{ group.summaryLink.url }}">{{ group.summaryLink.text }}</a>
123
123
  </div>
124
124
  {% endif %}