@ons/design-system 69.0.0 → 70.0.1
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.
- package/README.md +1 -0
- package/components/autosuggest/_autosuggest.scss +1 -1
- package/components/card/_macro.njk +3 -3
- package/components/card/_macro.spec.js +4 -4
- package/components/date-input/_macro.njk +71 -69
- package/components/date-input/_macro.spec.js +20 -5
- package/components/date-input/example-date-input-double-field.njk +27 -0
- package/components/date-input/example-date-input-single-field.njk +18 -0
- package/components/duration/_macro.njk +52 -48
- package/components/duration/_macro.spec.js +112 -4
- package/components/duration/example-duration-error-for-single-field.njk +1 -1
- package/components/duration/example-duration-single-field.njk +24 -0
- package/components/feedback/_macro.njk +1 -1
- package/components/header/_macro.njk +1 -1
- package/components/header/_macro.spec.js +1 -1
- package/components/icon/_macro.njk +10 -10
- package/components/icon/_macro.spec.js +4 -4
- package/components/metadata/_macro.njk +10 -10
- package/components/multiple-input-fields/_macro.njk +49 -0
- package/components/mutually-exclusive/mutually-exclusive.date.spec.js +121 -7
- package/components/mutually-exclusive/mutually-exclusive.duration.spec.js +121 -0
- package/components/section-navigation/_macro.njk +12 -12
- package/components/summary/_macro.njk +3 -3
- package/css/main.css +1 -1
- package/package.json +1 -1
- package/components/date-field-input/_macro.njk +0 -86
|
@@ -31,7 +31,35 @@ const EXAMPLE_MUTUALLY_EXCLUSIVE_DATE_PARAMS = {
|
|
|
31
31
|
deselectExclusiveOptionAdjective: 'deselected',
|
|
32
32
|
exclusiveOptions: [
|
|
33
33
|
{
|
|
34
|
-
id: 'date-exclusive-
|
|
34
|
+
id: 'date-exclusive-option',
|
|
35
|
+
name: 'no-paid-job',
|
|
36
|
+
value: 'no-paid-job',
|
|
37
|
+
label: {
|
|
38
|
+
text: 'I have never had a paid job',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const EXAMPLE_MUTUALLY_EXCLUSIVE_DATE_SINGLE_PARAMS = {
|
|
46
|
+
id: 'date-mutually-exclusive',
|
|
47
|
+
legendOrLabel: 'What year was your last MOT?',
|
|
48
|
+
description: 'For example, 2018',
|
|
49
|
+
year: {
|
|
50
|
+
label: {
|
|
51
|
+
text: 'Year',
|
|
52
|
+
},
|
|
53
|
+
name: 'year-exclusive',
|
|
54
|
+
},
|
|
55
|
+
mutuallyExclusive: {
|
|
56
|
+
or: 'Or',
|
|
57
|
+
deselectMessage: 'Selecting this will clear the date if one has been inputted',
|
|
58
|
+
deselectGroupAdjective: 'cleared',
|
|
59
|
+
deselectExclusiveOptionAdjective: 'deselected',
|
|
60
|
+
exclusiveOptions: [
|
|
61
|
+
{
|
|
62
|
+
id: 'date-exclusive-option',
|
|
35
63
|
name: 'no-paid-job',
|
|
36
64
|
value: 'no-paid-job',
|
|
37
65
|
label: {
|
|
@@ -57,11 +85,11 @@ describe('script: mutually-exclusive', () => {
|
|
|
57
85
|
|
|
58
86
|
describe('when the user clicks the mutually exclusive option', () => {
|
|
59
87
|
beforeEach(async () => {
|
|
60
|
-
await page.click('#date-exclusive-
|
|
88
|
+
await page.click('#date-exclusive-option');
|
|
61
89
|
});
|
|
62
90
|
|
|
63
91
|
it('then the mutually exclusive option should be checked', async () => {
|
|
64
|
-
const isChecked = await page.$eval('#date-exclusive-
|
|
92
|
+
const isChecked = await page.$eval('#date-exclusive-option', (node) => node.checked);
|
|
65
93
|
expect(isChecked).toBe(true);
|
|
66
94
|
});
|
|
67
95
|
|
|
@@ -85,7 +113,7 @@ describe('script: mutually-exclusive', () => {
|
|
|
85
113
|
|
|
86
114
|
describe('Given the user has checked the mutually exclusive exclusive option', () => {
|
|
87
115
|
beforeEach(async () => {
|
|
88
|
-
await page.click('#date-exclusive-
|
|
116
|
+
await page.click('#date-exclusive-option');
|
|
89
117
|
});
|
|
90
118
|
|
|
91
119
|
describe('when the user populates the dateInput', () => {
|
|
@@ -95,8 +123,8 @@ describe('script: mutually-exclusive', () => {
|
|
|
95
123
|
await page.type('#date-mutually-exclusive-year', '2018');
|
|
96
124
|
});
|
|
97
125
|
|
|
98
|
-
it('then the mutually exclusive option should be
|
|
99
|
-
const isChecked = await page.$eval('#date-exclusive-
|
|
126
|
+
it('then the mutually exclusive option should be unchecked', async () => {
|
|
127
|
+
const isChecked = await page.$eval('#date-exclusive-option', (node) => node.checked);
|
|
100
128
|
expect(isChecked).toBe(false);
|
|
101
129
|
});
|
|
102
130
|
|
|
@@ -127,7 +155,93 @@ describe('script: mutually-exclusive', () => {
|
|
|
127
155
|
|
|
128
156
|
describe('when the user clicks the mutually exclusive option', () => {
|
|
129
157
|
beforeEach(async () => {
|
|
130
|
-
await page.click('#date-exclusive-
|
|
158
|
+
await page.click('#date-exclusive-option');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('then the aria alert shouldnt say anything', async () => {
|
|
162
|
+
await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
|
|
163
|
+
|
|
164
|
+
const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
|
|
165
|
+
expect(alertText).toBe('');
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
describe('date-year', () => {
|
|
171
|
+
beforeEach(async () => {
|
|
172
|
+
await setTestPage('/test', renderComponent('date-input', EXAMPLE_MUTUALLY_EXCLUSIVE_DATE_SINGLE_PARAMS));
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe('Given the user populated the date input', () => {
|
|
176
|
+
beforeEach(async () => {
|
|
177
|
+
await page.type('#date-mutually-exclusive-year', '2018');
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
describe('when the user clicks the mutually exclusive option', () => {
|
|
181
|
+
beforeEach(async () => {
|
|
182
|
+
await page.click('#date-exclusive-option');
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('then the mutually exclusive option should be checked', async () => {
|
|
186
|
+
const isChecked = await page.$eval('#date-exclusive-option', (node) => node.checked);
|
|
187
|
+
expect(isChecked).toBe(true);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('then the date input should be cleared', async () => {
|
|
191
|
+
const yearValue = await page.$eval('#date-mutually-exclusive-year', (node) => node.value);
|
|
192
|
+
expect(yearValue).toBe('');
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('then the aria alert should tell the user that the date input has been cleared', async () => {
|
|
196
|
+
await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
|
|
197
|
+
|
|
198
|
+
const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
|
|
199
|
+
expect(alertText).toBe('What year was your last MOT? cleared.');
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
describe('Given the user has checked the mutually exclusive exclusive option', () => {
|
|
205
|
+
beforeEach(async () => {
|
|
206
|
+
await page.click('#date-exclusive-option');
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
describe('when the user populates the dateInput', () => {
|
|
210
|
+
beforeEach(async () => {
|
|
211
|
+
await page.type('#date-mutually-exclusive-year', '2018');
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('then the mutually exclusive option should be unchecked', async () => {
|
|
215
|
+
const isChecked = await page.$eval('#date-exclusive-option', (node) => node.checked);
|
|
216
|
+
expect(isChecked).toBe(false);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('then the aria alert should tell the user that the exclusive option has been unchecked', async () => {
|
|
220
|
+
await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
|
|
221
|
+
|
|
222
|
+
const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
|
|
223
|
+
expect(alertText).toBe('I have never had a paid job deselected.');
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
describe('Given the user has not populated the date input or checked the exclusive option', () => {
|
|
229
|
+
describe('when the user populates the date input', () => {
|
|
230
|
+
beforeEach(async () => {
|
|
231
|
+
await page.type('#date-mutually-exclusive-year', '2018');
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('then the aria alert shouldnt say anything', async () => {
|
|
235
|
+
await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
|
|
236
|
+
|
|
237
|
+
const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
|
|
238
|
+
expect(alertText).toBe('');
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
describe('when the user clicks the mutually exclusive option', () => {
|
|
243
|
+
beforeEach(async () => {
|
|
244
|
+
await page.click('#date-exclusive-option');
|
|
131
245
|
});
|
|
132
246
|
|
|
133
247
|
it('then the aria alert shouldnt say anything', async () => {
|
|
@@ -48,6 +48,40 @@ const EXAMPLE_MUTUALLY_EXCLUSIVE_DURATION_PARAMS = {
|
|
|
48
48
|
},
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
+
const EXAMPLE_MUTUALLY_EXCLUSIVE_DURATION_SINGLE_PARAMS = {
|
|
52
|
+
id: 'address-duration',
|
|
53
|
+
legendOrLabel: 'How long have you lived at this address?',
|
|
54
|
+
description: 'If you have lived at this address for less than a year then enter 0 into the year input.',
|
|
55
|
+
field1: {
|
|
56
|
+
id: 'address-duration-years',
|
|
57
|
+
name: 'address-duration-years',
|
|
58
|
+
suffix: {
|
|
59
|
+
text: 'Years',
|
|
60
|
+
id: 'address-duration-years-suffix',
|
|
61
|
+
},
|
|
62
|
+
attributes: {
|
|
63
|
+
min: 0,
|
|
64
|
+
max: 100,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
mutuallyExclusive: {
|
|
68
|
+
or: 'Or',
|
|
69
|
+
deselectMessage: 'Selecting this will clear the date if one has been inputted',
|
|
70
|
+
deselectGroupAdjective: 'cleared',
|
|
71
|
+
deselectExclusiveOptionAdjective: 'deselected',
|
|
72
|
+
exclusiveOptions: [
|
|
73
|
+
{
|
|
74
|
+
id: 'duration-exclusive-option',
|
|
75
|
+
name: 'no-duration',
|
|
76
|
+
value: 'no-duration',
|
|
77
|
+
label: {
|
|
78
|
+
text: 'I have not moved in to this address yet',
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
51
85
|
describe('script: mutually-exclusive', () => {
|
|
52
86
|
describe('duration', () => {
|
|
53
87
|
beforeEach(async () => {
|
|
@@ -140,4 +174,91 @@ describe('script: mutually-exclusive', () => {
|
|
|
140
174
|
});
|
|
141
175
|
});
|
|
142
176
|
});
|
|
177
|
+
|
|
178
|
+
describe('duration-single', () => {
|
|
179
|
+
beforeEach(async () => {
|
|
180
|
+
await setTestPage('/test', renderComponent('duration', EXAMPLE_MUTUALLY_EXCLUSIVE_DURATION_SINGLE_PARAMS));
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe('Given the user populated the duration', () => {
|
|
184
|
+
beforeEach(async () => {
|
|
185
|
+
await page.type('#address-duration-years', '2');
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
describe('when the user clicks the mutually exclusive option', () => {
|
|
189
|
+
beforeEach(async () => {
|
|
190
|
+
await page.click('#duration-exclusive-option');
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('then the mutually exclusive option should be checked', async () => {
|
|
194
|
+
const isChecked = await page.$eval('#duration-exclusive-option', (node) => node.checked);
|
|
195
|
+
expect(isChecked).toBe(true);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('then the inputs should be cleared', async () => {
|
|
199
|
+
const yearsValue = await page.$eval('#address-duration-years', (node) => node.value);
|
|
200
|
+
expect(yearsValue).toBe('');
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it('then the aria alert should tell the user that the inputs have been cleared', async () => {
|
|
204
|
+
await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
|
|
205
|
+
|
|
206
|
+
const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
|
|
207
|
+
expect(alertText).toBe('How long have you lived at this address? cleared.');
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
describe('Given the user has checked the mutually exclusive exclusive option', () => {
|
|
213
|
+
beforeEach(async () => {
|
|
214
|
+
await page.click('#duration-exclusive-option');
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
describe('when the user populates the duration fields', () => {
|
|
218
|
+
beforeEach(async () => {
|
|
219
|
+
await page.type('#address-duration-years', '2');
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('then the exclusive option should be unchecked', async () => {
|
|
223
|
+
const isChecked = await page.$eval('#duration-exclusive-option', (node) => node.checked);
|
|
224
|
+
expect(isChecked).toBe(false);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('then the aria alert should tell the user that the exclusive option has been unchecked', async () => {
|
|
228
|
+
await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
|
|
229
|
+
|
|
230
|
+
const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
|
|
231
|
+
expect(alertText).toBe('I have not moved in to this address yet deselected.');
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
describe('Given the user has not populated the duration inputs or checked the exclusive option', () => {
|
|
237
|
+
describe('when the user populates the duration inputs', () => {
|
|
238
|
+
beforeEach(async () => {
|
|
239
|
+
await page.type('#address-duration-years', '2');
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it('then the aria alert shouldnt say anything', async () => {
|
|
243
|
+
await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
|
|
244
|
+
|
|
245
|
+
const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
|
|
246
|
+
expect(alertText).toBe('');
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
describe('when the user clicks the mutually exclusive option', () => {
|
|
251
|
+
beforeEach(async () => {
|
|
252
|
+
await page.click('#duration-exclusive-option');
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it('then the aria alert shouldnt say anything', async () => {
|
|
256
|
+
await page.waitForTimeout(SCREEN_READER_TIMEOUT_DELAY);
|
|
257
|
+
|
|
258
|
+
const alertText = await page.$eval('.ons-js-exclusive-alert', (node) => node.textContent);
|
|
259
|
+
expect(alertText).toBe('');
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
});
|
|
143
264
|
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{% macro onsSectionNavigation(params) %}
|
|
2
|
-
{% set headingLevel = params.headingLevel |
|
|
3
|
-
{% set sectionTitleHeadingLevel =
|
|
2
|
+
{% set headingLevel = params.headingLevel | default(2) %}
|
|
3
|
+
{% set sectionTitleHeadingLevel = headingLevel + 1 %}
|
|
4
4
|
<nav class="ons-section-nav{% if params.variants == 'vertical' %} ons-section-nav--vertical{% endif %} {% if params.classes %} {{ params.classes }} {% endif %}"{% if params.id %} id="{{ params.id }}"{% endif %} aria-labelledby="{{ params.hiddenTitleId | default("section-menu-nav-title")}}">
|
|
5
|
-
|
|
5
|
+
<h{{ headingLevel }} class="ons-u-vh" id="{{ params.hiddenTitleId | default("section-menu-nav-title") }}">{{ params.hiddenTitle | default("Pages in this section") }}</h{{ headingLevel }}>
|
|
6
6
|
{% if params.sections %}
|
|
7
7
|
{% for section in params.sections %}
|
|
8
|
-
{% set sectionItemHeadingLevel =
|
|
8
|
+
{% set sectionItemHeadingLevel = headingLevel + 2 if section.title else headingLevel + 1 %}
|
|
9
9
|
<div class="ons-section-nav__sub">
|
|
10
10
|
{% if section.title %}
|
|
11
11
|
<h{{ sectionTitleHeadingLevel }} class="ons-u-fs-r--b ons-u-mb-s">{{ section.title }}</h{{ sectionTitleHeadingLevel }}>
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
{% set isCurrent = false %}
|
|
19
19
|
{% endif %}
|
|
20
20
|
<li class="ons-section-nav__item{% if item.classes %}{{ ' ' + item.classes }}{% endif %}{% if isCurrent == true %} ons-section-nav__item--active{% endif %}">
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
{% if isCurrent == true %}
|
|
22
|
+
<h{{ sectionItemHeadingLevel }} class="ons-section-nav__link ons-section-nav__item-header" href="{{ item.url }}" aria-current="location">{{ item.title }}</h{{ sectionItemHeadingLevel }}>
|
|
23
|
+
{% else %}
|
|
24
|
+
<a class="ons-section-nav__link" href="{{ item.url }}">{{ item.title }}</a>
|
|
25
|
+
{% endif %}
|
|
26
|
+
{% if item.anchors and isCurrent == true %}
|
|
27
27
|
<ul class="ons-section-nav__sub-items ons-list ons-list--dashed ons-u-mt-xs ons-u-mb-xs">
|
|
28
28
|
{% for anchor in item.anchors %}
|
|
29
29
|
<li class="ons-section-nav__item ons-list__item">
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
{% endif %}
|
|
44
44
|
<ul class="ons-section-nav__list">
|
|
45
45
|
{% for item in params.itemsList %}
|
|
46
|
-
{% set sectionItemHeadingLevel =
|
|
46
|
+
{% set sectionItemHeadingLevel = headingLevel + 2 if params.title else headingLevel + 1 %}
|
|
47
47
|
{% if (params.currentPath and item.url == params.currentPath) or (params.tabQuery and params.tabQuery == item.title|lower) %}
|
|
48
48
|
{% set isCurrent = true %}
|
|
49
49
|
{% else %}
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
{% endif %}
|
|
52
52
|
<li class="ons-section-nav__item{% if item.classes %}{{ ' ' + item.classes }}{% endif %}{% if isCurrent == true %} ons-section-nav__item--active{% endif %}">
|
|
53
53
|
{% if isCurrent == true %}
|
|
54
|
-
<h{{ sectionItemHeadingLevel}} class="ons-section-nav__link ons-section-nav__item-header" href="{{ item.url }}" aria-current="location">{{ item.title }}</h{{ headingLevel + 2 if section.title else headingLevel + 1 }}>
|
|
54
|
+
<h{{ sectionItemHeadingLevel }} class="ons-section-nav__link ons-section-nav__item-header" href="{{ item.url }}" aria-current="location">{{ item.title }}</h{{ headingLevel + 2 if section.title else headingLevel + 1 }}>
|
|
55
55
|
{% else %}
|
|
56
56
|
<a class="ons-section-nav__link" href="{{ item.url }}">{{ item.title }}</a>
|
|
57
57
|
{% endif %}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{% macro onsSummary(params) %}
|
|
2
2
|
{% set className = "ons-summary" %}
|
|
3
|
-
{% set
|
|
3
|
+
{% set headingLevel = 2 %}
|
|
4
4
|
|
|
5
5
|
{% if params.variant == "hub" %}
|
|
6
6
|
{% set variantHub = true %}
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
{% for summary in params.summaries %}
|
|
18
18
|
{% if summary.summaryTitle %}
|
|
19
19
|
<h2 class="ons-summary__title ons-u-mb-m{{ " ons-u-mt-m" if loop.index > 1 else "" }}">{{ summary.summaryTitle }}</h2>
|
|
20
|
-
{% set
|
|
20
|
+
{% set headingLevel = 3 %}
|
|
21
21
|
{% endif %}
|
|
22
22
|
{% for group in summary.groups %}
|
|
23
23
|
<div {% if group.id %}id="{{ group.id }}" {% endif %} class="ons-summary__group{{ variantClasses }}">
|
|
24
24
|
{% if group.groupTitle %}
|
|
25
|
-
<h{{
|
|
25
|
+
<h{{ headingLevel }} class="ons-summary__group-title">{{ group.groupTitle }}</h{{ headingLevel }}>
|
|
26
26
|
{% endif %}
|
|
27
27
|
{% if group.rows %}
|
|
28
28
|
<dl class="ons-summary__items">
|