@ons/design-system 72.9.0 → 72.9.2
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/components/button/_button.scss +10 -0
- package/components/card/_macro.njk +17 -4
- package/components/card/_macro.spec.js +109 -252
- package/components/card/_test_examples.js +56 -0
- package/components/card/example-card-set-with-headline-figures.njk +1 -4
- package/components/chart/_macro.njk +2 -1
- package/components/chart/_macro.spec.js +17 -121
- package/components/chart/area-chart.js +1 -0
- package/components/chart/bar-chart.js +2 -2
- package/components/chart/chart.js +13 -8
- package/components/chart/common-chart-options.js +0 -4
- package/components/details-panel/_macro.njk +5 -1
- package/components/details-panel/_macro.spec.js +22 -0
- package/components/document-list/_document-list.scss +5 -13
- package/components/document-list/_macro.njk +14 -17
- package/components/document-list/_macro.spec.js +3 -3
- package/components/fieldset/_macro.spec.js +200 -120
- package/components/fieldset/_test_examples.js +15 -0
- package/components/header/_header.scss +11 -0
- package/components/header/_macro.njk +11 -6
- package/components/header/_macro.spec.js +113 -3
- package/components/hero/_macro.spec.js +1 -1
- package/components/icon/_macro.njk +14 -24
- package/components/language-selector/_macro.njk +6 -3
- package/components/navigation/navigation.js +57 -58
- package/components/navigation/navigation.spec.js +6 -10
- package/components/summary/_macro.njk +4 -1
- package/components/table-of-contents/_macro.njk +2 -12
- package/components/table-of-contents/_macro.spec.js +7 -0
- package/components/table-of-contents/example-table-of-contents-related-links-with-button.njk +1 -2
- package/components/table-of-contents/table-of-contents.js +43 -26
- package/css/main.css +1 -1
- package/package.json +1 -1
- package/scripts/main.es5.js +1 -1
- package/scripts/main.js +1 -1
- package/components/chart/example-bar-with-line-chart.njk +0 -64
|
@@ -1,189 +1,269 @@
|
|
|
1
1
|
/** @jest-environment jsdom */
|
|
2
2
|
|
|
3
3
|
import * as cheerio from 'cheerio';
|
|
4
|
-
|
|
5
4
|
import axe from '../../tests/helpers/axe';
|
|
6
5
|
import { renderComponent, templateFaker } from '../../tests/helpers/rendering';
|
|
6
|
+
import { EXAMPLE_FIELDSET, EXAMPLE_FIELDSET_NO_ID, EXAMPLE_FIELDSET_NO_LEGEND } from './_test_examples';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
};
|
|
8
|
+
describe('FOR: Macro: Fieldset', () => {
|
|
9
|
+
describe('GIVEN: Params: id', () => {
|
|
10
|
+
describe('WHEN: id is provided', () => {
|
|
11
|
+
const $ = cheerio.load(renderComponent('fieldset', EXAMPLE_FIELDSET));
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
test('THEN: renders fieldset with provided id', () => {
|
|
14
|
+
expect($('.ons-fieldset').attr('id')).toBe('example-fieldset');
|
|
15
|
+
});
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
test('THEN: legend has correct aria-describedby attribute', () => {
|
|
18
|
+
const ariaDescByVal = $('.ons-fieldset__legend').attr('aria-describedby');
|
|
19
|
+
expect(ariaDescByVal).toBe('example-fieldset-legend-description');
|
|
20
|
+
});
|
|
21
|
+
});
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
describe('WHEN: id is not provided', () => {
|
|
24
|
+
const $ = cheerio.load(renderComponent('fieldset', EXAMPLE_FIELDSET_NO_ID));
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
test('THEN: description has default id', () => {
|
|
27
|
+
const id = $('.ons-fieldset__description').attr('id');
|
|
28
|
+
expect(id).toBe('legend-description');
|
|
29
|
+
});
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
test('THEN: legend has correct aria-describedby attribute', () => {
|
|
32
|
+
const ariaDescByVal = $('.ons-fieldset__legend').attr('aria-describedby');
|
|
33
|
+
expect(ariaDescByVal).toBe('legend-description');
|
|
34
|
+
});
|
|
35
|
+
});
|
|
33
36
|
});
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
describe('GIVEN: Params: legend', () => {
|
|
39
|
+
describe('WHEN: legend is provided', () => {
|
|
40
|
+
const $ = cheerio.load(renderComponent('fieldset', EXAMPLE_FIELDSET));
|
|
37
41
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
test('THEN: jest-axe checks pass', async () => {
|
|
43
|
+
const results = await axe($.html());
|
|
44
|
+
expect(results).toHaveNoViolations();
|
|
45
|
+
});
|
|
41
46
|
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
test('THEN: renders legend with provided text', () => {
|
|
48
|
+
const title = $('.ons-fieldset__legend-title').text().trim();
|
|
49
|
+
expect(title).toBe('Fieldset legend');
|
|
50
|
+
});
|
|
44
51
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
52
|
+
test('THEN: legend has correct aria-describedby attribute', () => {
|
|
53
|
+
const ariaDescByVal = $('.ons-fieldset__legend').attr('aria-describedby');
|
|
54
|
+
expect(ariaDescByVal).toBe('example-fieldset-legend-description');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('THEN: legend has the legend with description class', () => {
|
|
58
|
+
expect($('.ons-fieldset__legend').hasClass('ons-fieldset__legend--with-description')).toBe(true);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
48
61
|
|
|
49
|
-
|
|
50
|
-
|
|
62
|
+
describe('WHEN: legend is not provided and legendIsQuestionTitle is not set', () => {
|
|
63
|
+
const $ = cheerio.load(renderComponent('fieldset', EXAMPLE_FIELDSET_NO_LEGEND));
|
|
51
64
|
|
|
52
|
-
|
|
53
|
-
|
|
65
|
+
test('THEN: does not render fieldset or legend', () => {
|
|
66
|
+
expect($('.ons-fieldset').length).toBe(0);
|
|
67
|
+
expect($('.ons-fieldset__legend').length).toBe(0);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
54
70
|
});
|
|
55
71
|
|
|
56
|
-
|
|
57
|
-
|
|
72
|
+
describe('GIVEN: Params: classes', () => {
|
|
73
|
+
describe('WHEN: classes are provided', () => {
|
|
74
|
+
const $ = cheerio.load(
|
|
75
|
+
renderComponent('fieldset', {
|
|
76
|
+
...EXAMPLE_FIELDSET,
|
|
77
|
+
classes: 'extra-class another-extra-class',
|
|
78
|
+
}),
|
|
79
|
+
);
|
|
58
80
|
|
|
59
|
-
|
|
60
|
-
|
|
81
|
+
test('THEN: renders fieldset with provided classes', () => {
|
|
82
|
+
expect($('.ons-fieldset').hasClass('extra-class')).toBe(true);
|
|
83
|
+
expect($('.ons-fieldset').hasClass('another-extra-class')).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
61
86
|
});
|
|
62
87
|
|
|
63
|
-
|
|
64
|
-
|
|
88
|
+
describe('GIVEN: Params: legendClasses', () => {
|
|
89
|
+
describe('WHEN: legendClasses are provided', () => {
|
|
90
|
+
const $ = cheerio.load(
|
|
91
|
+
renderComponent('fieldset', {
|
|
92
|
+
...EXAMPLE_FIELDSET,
|
|
93
|
+
legendClasses: 'extra-class another-extra-class',
|
|
94
|
+
}),
|
|
95
|
+
);
|
|
65
96
|
|
|
66
|
-
|
|
97
|
+
test('THEN: renders legend with provided classes', () => {
|
|
98
|
+
expect($('.ons-fieldset__legend').hasClass('extra-class')).toBe(true);
|
|
99
|
+
expect($('.ons-fieldset__legend').hasClass('another-extra-class')).toBe(true);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
67
102
|
});
|
|
68
103
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
104
|
+
describe('GIVEN: Params: attributes', () => {
|
|
105
|
+
describe('WHEN: attributes are provided', () => {
|
|
106
|
+
const $ = cheerio.load(
|
|
107
|
+
renderComponent('fieldset', {
|
|
108
|
+
...EXAMPLE_FIELDSET,
|
|
109
|
+
attributes: {
|
|
110
|
+
a: 123,
|
|
111
|
+
b: 456,
|
|
112
|
+
},
|
|
113
|
+
}),
|
|
114
|
+
);
|
|
76
115
|
|
|
77
|
-
|
|
78
|
-
|
|
116
|
+
test('THEN: renders fieldset with provided attributes', () => {
|
|
117
|
+
expect($('.ons-fieldset').attr('a')).toBe('123');
|
|
118
|
+
expect($('.ons-fieldset').attr('b')).toBe('456');
|
|
119
|
+
});
|
|
120
|
+
});
|
|
79
121
|
});
|
|
80
122
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
123
|
+
describe('GIVEN: Params: dontWrap', () => {
|
|
124
|
+
describe('WHEN: dontWrap is set to true', () => {
|
|
125
|
+
const $ = cheerio.load(
|
|
126
|
+
renderComponent(
|
|
127
|
+
'fieldset',
|
|
128
|
+
{
|
|
129
|
+
...EXAMPLE_FIELDSET,
|
|
130
|
+
dontWrap: true,
|
|
131
|
+
},
|
|
132
|
+
'Example content...',
|
|
133
|
+
),
|
|
134
|
+
);
|
|
88
135
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
136
|
+
test('THEN: renders without fieldset wrapper', () => {
|
|
137
|
+
expect($('.ons-fieldset').length).toBe(0);
|
|
138
|
+
expect($('.ons-input-items').length).toBe(1);
|
|
139
|
+
});
|
|
92
140
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
attributes: {
|
|
98
|
-
a: 123,
|
|
99
|
-
b: 456,
|
|
100
|
-
},
|
|
101
|
-
}),
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
expect($('.ons-fieldset').attr('a')).toBe('123');
|
|
105
|
-
expect($('.ons-fieldset').attr('b')).toBe('456');
|
|
106
|
-
});
|
|
141
|
+
test('THEN: renders content inside ons-input-items div', () => {
|
|
142
|
+
expect($('.ons-input-items').html()).toBe('Example content...');
|
|
143
|
+
});
|
|
144
|
+
});
|
|
107
145
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
renderComponent('fieldset', {
|
|
111
|
-
...EXAMPLE_FIELDSET_BASIC,
|
|
112
|
-
dontWrap: true,
|
|
113
|
-
}),
|
|
114
|
-
);
|
|
146
|
+
describe('WHEN: dontWrap is set to true and legend is not provided', () => {
|
|
147
|
+
const $ = cheerio.load(renderComponent('fieldset', { ...EXAMPLE_FIELDSET_NO_LEGEND, dontWrap: true }));
|
|
115
148
|
|
|
116
|
-
|
|
117
|
-
|
|
149
|
+
test('THEN: renders ons-input-items div without fieldset or legend', () => {
|
|
150
|
+
expect($('.ons-fieldset').length).toBe(0);
|
|
151
|
+
expect($('.ons-fieldset__legend').length).toBe(0);
|
|
152
|
+
expect($('.ons-input-items').length).toBe(1);
|
|
153
|
+
});
|
|
154
|
+
});
|
|
118
155
|
});
|
|
119
156
|
|
|
120
|
-
|
|
121
|
-
|
|
157
|
+
describe('GIVEN: Content', () => {
|
|
158
|
+
describe('WHEN: content is provided', () => {
|
|
159
|
+
const $ = cheerio.load(renderComponent('fieldset', EXAMPLE_FIELDSET, 'Example content...'));
|
|
122
160
|
|
|
123
|
-
|
|
124
|
-
|
|
161
|
+
test('THEN: renders fieldset with provided content', () => {
|
|
162
|
+
const content = $('.ons-fieldset').html();
|
|
163
|
+
expect(content).toContain('Example content...');
|
|
164
|
+
});
|
|
165
|
+
});
|
|
125
166
|
});
|
|
126
167
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
168
|
+
describe('GIVEN: Params: error', () => {
|
|
169
|
+
describe('WHEN: error is provided', () => {
|
|
170
|
+
const faker = templateFaker();
|
|
171
|
+
const errorSpy = faker.spy('error');
|
|
130
172
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
173
|
+
faker.renderComponent('fieldset', {
|
|
174
|
+
...EXAMPLE_FIELDSET,
|
|
175
|
+
error: { text: 'Error message' },
|
|
176
|
+
});
|
|
135
177
|
|
|
136
|
-
|
|
137
|
-
|
|
178
|
+
test('THEN: wraps fieldset with error component', () => {
|
|
179
|
+
expect(errorSpy.occurrences.length).toBe(1);
|
|
180
|
+
expect(errorSpy.occurrences[0]).toEqual({ text: 'Error message' });
|
|
181
|
+
});
|
|
138
182
|
});
|
|
139
183
|
});
|
|
140
184
|
|
|
141
|
-
describe('
|
|
142
|
-
|
|
143
|
-
const $ = cheerio.load(
|
|
185
|
+
describe('GIVEN: Params: legendIsQuestionTitle', () => {
|
|
186
|
+
describe('WHEN: legendIsQuestionTitle is set to true and legend is provided', () => {
|
|
187
|
+
const $ = cheerio.load(
|
|
188
|
+
renderComponent('fieldset', {
|
|
189
|
+
...EXAMPLE_FIELDSET,
|
|
190
|
+
legendIsQuestionTitle: true,
|
|
191
|
+
}),
|
|
192
|
+
);
|
|
144
193
|
|
|
145
|
-
|
|
146
|
-
|
|
194
|
+
test('THEN: jest-axe checks pass', async () => {
|
|
195
|
+
const results = await axe($.html());
|
|
196
|
+
expect(results).toHaveNoViolations();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test('THEN: description has correct classes', () => {
|
|
200
|
+
expect($('.ons-fieldset__description').hasClass('ons-fieldset__description--title')).toBe(true);
|
|
201
|
+
expect($('.ons-fieldset__description').hasClass('ons-u-mb-l')).toBe(true);
|
|
202
|
+
});
|
|
147
203
|
});
|
|
148
204
|
|
|
149
|
-
|
|
150
|
-
const $ = cheerio.load(renderComponent('fieldset',
|
|
151
|
-
const titleTag = $('.ons-fieldset__legend-title')[0].tagName;
|
|
205
|
+
describe('WHEN: legendIsQuestionTitle is not set and legend is provided', () => {
|
|
206
|
+
const $ = cheerio.load(renderComponent('fieldset', EXAMPLE_FIELDSET));
|
|
152
207
|
|
|
153
|
-
|
|
208
|
+
test('THEN: renders legend title in a span', () => {
|
|
209
|
+
const titleTag = $('.ons-fieldset__legend-title')[0].tagName;
|
|
210
|
+
expect(titleTag).toBe('span');
|
|
211
|
+
});
|
|
154
212
|
});
|
|
213
|
+
});
|
|
155
214
|
|
|
156
|
-
|
|
215
|
+
describe('GIVEN: Params: legendTitleClasses', () => {
|
|
216
|
+
describe('WHEN: legendTitleClasses are provided with legendIsQuestionTitle set to true', () => {
|
|
157
217
|
const $ = cheerio.load(
|
|
158
218
|
renderComponent('fieldset', {
|
|
159
|
-
...
|
|
160
|
-
legendTitleClasses: 'extra-class another-extra-class',
|
|
219
|
+
...EXAMPLE_FIELDSET,
|
|
161
220
|
legendIsQuestionTitle: true,
|
|
221
|
+
legendTitleClasses: 'extra-class another-extra-class',
|
|
162
222
|
}),
|
|
163
223
|
);
|
|
164
224
|
|
|
165
|
-
|
|
166
|
-
|
|
225
|
+
test('THEN: renders legend title with provided classes', () => {
|
|
226
|
+
expect($('.ons-fieldset__legend-title').hasClass('extra-class')).toBe(true);
|
|
227
|
+
expect($('.ons-fieldset__legend-title').hasClass('another-extra-class')).toBe(true);
|
|
228
|
+
});
|
|
167
229
|
});
|
|
168
230
|
|
|
169
|
-
|
|
231
|
+
describe('WHEN: legendTitleClasses are provided without legendIsQuestionTitle', () => {
|
|
170
232
|
const $ = cheerio.load(
|
|
171
233
|
renderComponent('fieldset', {
|
|
172
|
-
...
|
|
234
|
+
...EXAMPLE_FIELDSET,
|
|
173
235
|
legendTitleClasses: 'extra-class another-extra-class',
|
|
174
|
-
legendIsQuestionTitle: true,
|
|
175
236
|
}),
|
|
176
237
|
);
|
|
177
238
|
|
|
178
|
-
|
|
179
|
-
|
|
239
|
+
test('THEN: legend title does not have additional classes', () => {
|
|
240
|
+
expect($('.ons-fieldset__legend-title').hasClass('extra-class')).toBe(false);
|
|
241
|
+
expect($('.ons-fieldset__legend-title').hasClass('another-extra-class')).toBe(false);
|
|
242
|
+
});
|
|
180
243
|
});
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
describe('GIVEN: Params: description', () => {
|
|
247
|
+
describe('WHEN: description is not provided', () => {
|
|
248
|
+
const $ = cheerio.load(
|
|
249
|
+
renderComponent('fieldset', {
|
|
250
|
+
...EXAMPLE_FIELDSET,
|
|
251
|
+
description: undefined,
|
|
252
|
+
}),
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
test('THEN: fieldset renders without description', () => {
|
|
256
|
+
expect($('.ons-fieldset__description').length).toBe(0);
|
|
257
|
+
});
|
|
181
258
|
|
|
182
|
-
|
|
183
|
-
|
|
259
|
+
test('THEN: legend does not have aria-describedby attribute', () => {
|
|
260
|
+
const ariaDescByVal = $('.ons-fieldset__legend').attr('aria-describedby');
|
|
261
|
+
expect(ariaDescByVal).toBeUndefined();
|
|
262
|
+
});
|
|
184
263
|
|
|
185
|
-
|
|
186
|
-
|
|
264
|
+
test('THEN: legend does not have ons-fieldset__legend--with-description class', () => {
|
|
265
|
+
expect($('.ons-fieldset__legend').hasClass('ons-fieldset__legend--with-description')).toBe(false);
|
|
266
|
+
});
|
|
187
267
|
});
|
|
188
268
|
});
|
|
189
269
|
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const EXAMPLE_FIELDSET = {
|
|
2
|
+
id: 'example-fieldset',
|
|
3
|
+
legend: 'Fieldset legend',
|
|
4
|
+
description: 'A fieldset description',
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const EXAMPLE_FIELDSET_NO_LEGEND = {
|
|
8
|
+
id: 'example-fieldset',
|
|
9
|
+
description: 'A fieldset description',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const EXAMPLE_FIELDSET_NO_ID = {
|
|
13
|
+
legend: 'Fieldset legend',
|
|
14
|
+
description: 'A fieldset description',
|
|
15
|
+
};
|
|
@@ -243,8 +243,19 @@
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
&-nav-menu {
|
|
246
|
+
// applies styles for non-js variant
|
|
246
247
|
background-color: var(--ons-color-branded-tint);
|
|
248
|
+
border-bottom: 1px solid var(--ons-color-ocean-blue);
|
|
247
249
|
width: 100%;
|
|
250
|
+
margin-bottom: 0;
|
|
251
|
+
padding-bottom: 1rem;
|
|
252
|
+
|
|
253
|
+
// updates styles when js is enabled
|
|
254
|
+
.ons-js-enabled & {
|
|
255
|
+
border-bottom: 0;
|
|
256
|
+
margin-bottom: 1rem;
|
|
257
|
+
padding-bottom: 0;
|
|
258
|
+
}
|
|
248
259
|
|
|
249
260
|
&__key-list {
|
|
250
261
|
border-bottom: 1px solid var(--ons-color-ocean-blue);
|
|
@@ -188,7 +188,7 @@
|
|
|
188
188
|
{{
|
|
189
189
|
onsButton({
|
|
190
190
|
"text": params.menuLinks.toggleMenuButton.text | default("Menu"),
|
|
191
|
-
"classes": "ons-u-fs-s--b ons-js-toggle-nav-menu button-nav",
|
|
191
|
+
"classes": "ons-u-fs-s--b ons-js-toggle-nav-menu button-nav active disabled",
|
|
192
192
|
"type": "button",
|
|
193
193
|
"variants": "menu",
|
|
194
194
|
"iconType": "chevron",
|
|
@@ -196,24 +196,27 @@
|
|
|
196
196
|
"attributes": {
|
|
197
197
|
"aria-label": params.menuLinks.toggleMenuButton.ariaLabel | default("Toggle menu"),
|
|
198
198
|
"aria-controls": params.menuLinks.id,
|
|
199
|
-
"aria-expanded": "
|
|
199
|
+
"aria-expanded": "true",
|
|
200
|
+
"aria-disabled": "true"
|
|
200
201
|
}
|
|
201
202
|
})
|
|
202
203
|
}}
|
|
203
204
|
</div>
|
|
204
205
|
{% endif %}
|
|
206
|
+
|
|
205
207
|
{% if params.searchLinks %}
|
|
206
208
|
<div class="ons-header__links ons-grid__col">
|
|
207
209
|
{{
|
|
208
210
|
onsButton({
|
|
209
|
-
"classes": "ons-u-fs-s--b ons-js-toggle-header-search ons-btn--
|
|
211
|
+
"classes": "ons-u-fs-s--b ons-js-toggle-header-search ons-btn--close ons-btn--search-icon active disabled",
|
|
210
212
|
"type": "button",
|
|
211
213
|
"variants": "search",
|
|
212
214
|
"iconType": "search",
|
|
213
215
|
"attributes": {
|
|
214
216
|
"aria-label": params.searchLinks.searchButtonAriaLabel | default("Toggle search"),
|
|
215
217
|
"aria-controls": params.searchLinks.id,
|
|
216
|
-
"aria-expanded": "
|
|
218
|
+
"aria-expanded": "true",
|
|
219
|
+
"aria-disabled": "true"
|
|
217
220
|
}
|
|
218
221
|
})
|
|
219
222
|
}}
|
|
@@ -261,9 +264,10 @@
|
|
|
261
264
|
|
|
262
265
|
{% if params.variants == "basic" and params.menuLinks %}
|
|
263
266
|
<nav
|
|
264
|
-
class="ons-
|
|
267
|
+
class="ons-js-nav-menu ons-header-nav-menu ons-u-pt-2xl"
|
|
265
268
|
id="{{ params.menuLinks.id }}"
|
|
266
269
|
aria-label="{{ params.menuLinks.ariaLabel | default("Menu navigation") }}"
|
|
270
|
+
aria-hidden="false"
|
|
267
271
|
>
|
|
268
272
|
{% if params.menuLinks.keyLinks %}
|
|
269
273
|
<div class="ons-container">
|
|
@@ -334,9 +338,10 @@
|
|
|
334
338
|
|
|
335
339
|
{% if params.variants == "basic" and params.searchLinks %}
|
|
336
340
|
<nav
|
|
337
|
-
class="ons-
|
|
341
|
+
class="ons-js-header-search ons-header-nav-search {{ params.searchLinks.classes }}"
|
|
338
342
|
id="{{ params.searchLinks.id }}"
|
|
339
343
|
aria-label="{{ params.searchLinks.searchNavigationAriaLabel | default('Search navigation') }}"
|
|
344
|
+
aria-hidden="false"
|
|
340
345
|
>
|
|
341
346
|
<div class="ons-container">
|
|
342
347
|
<div class="ons-header-nav-search__input">
|
|
@@ -5,6 +5,7 @@ import * as cheerio from 'cheerio';
|
|
|
5
5
|
import axe from '../../tests/helpers/axe';
|
|
6
6
|
import { renderComponent, templateFaker } from '../../tests/helpers/rendering';
|
|
7
7
|
import { mapAll } from '../../tests/helpers/cheerio';
|
|
8
|
+
import NavigationToggle from '../../components/navigation/navigation';
|
|
8
9
|
|
|
9
10
|
import {
|
|
10
11
|
EXAMPLE_HEADER_BASIC,
|
|
@@ -15,6 +16,8 @@ import {
|
|
|
15
16
|
EXAMPLE_HEADER_LANGUAGE_CONFIG,
|
|
16
17
|
EXAMPLE_HEADER_NAVIGATION_WITH_SUBNAVIGATION_CONFIG,
|
|
17
18
|
EXAMPLE_HEADER_NAVIGATION_WITH_SITESEARCHAUTOSUGGEST,
|
|
19
|
+
EXAMPLE_HEADER_MENU_LINKS,
|
|
20
|
+
EXAMPLE_HEADER_SEARCH_AND_MENU_LINKS,
|
|
18
21
|
} from './_test-examples';
|
|
19
22
|
|
|
20
23
|
describe('FOR: Macro: Header', () => {
|
|
@@ -794,13 +797,14 @@ describe('FOR: Macro: Header', () => {
|
|
|
794
797
|
test('THEN: renders search icon button', () => {
|
|
795
798
|
expect(buttonSpy.occurrences[0]).toEqual({
|
|
796
799
|
iconType: 'search',
|
|
797
|
-
classes: 'ons-u-fs-s--b ons-js-toggle-header-search ons-btn--
|
|
800
|
+
classes: 'ons-u-fs-s--b ons-js-toggle-header-search ons-btn--close ons-btn--search-icon active disabled',
|
|
798
801
|
type: 'button',
|
|
799
802
|
variants: 'search',
|
|
800
803
|
attributes: {
|
|
801
|
-
'aria-label': 'Example aria label',
|
|
802
|
-
'aria-expanded': 'false',
|
|
803
804
|
'aria-controls': 'search-links-id',
|
|
805
|
+
'aria-expanded': 'true',
|
|
806
|
+
'aria-label': 'Example aria label',
|
|
807
|
+
'aria-disabled': 'true',
|
|
804
808
|
},
|
|
805
809
|
});
|
|
806
810
|
});
|
|
@@ -880,5 +884,111 @@ describe('FOR: Macro: Header', () => {
|
|
|
880
884
|
expect($('.ons-header-nav-search').hasClass('custom-class')).toBe(true);
|
|
881
885
|
});
|
|
882
886
|
});
|
|
887
|
+
|
|
888
|
+
describe('WHEN: using basic header variant and search is active & disabled by default before JS loads', () => {
|
|
889
|
+
const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_SEARCH_LINKS, variants: 'basic' }));
|
|
890
|
+
const $searchBtn = $('.ons-js-toggle-header-search');
|
|
891
|
+
|
|
892
|
+
test('THEN: adds the "active" class to the search toggle button', () => {
|
|
893
|
+
expect($searchBtn.hasClass('active')).toBe(true);
|
|
894
|
+
});
|
|
895
|
+
|
|
896
|
+
test('THEN: adds the "disabled" class to the search toggle button', () => {
|
|
897
|
+
expect($searchBtn.hasClass('disabled')).toBe(true);
|
|
898
|
+
});
|
|
899
|
+
|
|
900
|
+
test('THEN: sets aria-disabled="true" on the search toggle button', () => {
|
|
901
|
+
expect($searchBtn.attr('aria-disabled')).toBe('true');
|
|
902
|
+
});
|
|
903
|
+
});
|
|
904
|
+
});
|
|
905
|
+
|
|
906
|
+
describe('GIVEN: Params: menuLinks', () => {
|
|
907
|
+
describe('WHEN: using basic header variant and menu toggle is rendered before JS loads', () => {
|
|
908
|
+
const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_MENU_LINKS));
|
|
909
|
+
const $menuBtn = $('.ons-js-toggle-nav-menu');
|
|
910
|
+
|
|
911
|
+
test('THEN: adds the "active" class to the menu toggle button', () => {
|
|
912
|
+
expect($menuBtn.hasClass('active')).toBe(true);
|
|
913
|
+
});
|
|
914
|
+
|
|
915
|
+
test('THEN: adds the "disabled" class to the menu toggle button', () => {
|
|
916
|
+
expect($menuBtn.hasClass('disabled')).toBe(true);
|
|
917
|
+
});
|
|
918
|
+
|
|
919
|
+
test('THEN: sets aria-disabled="true" on the menu toggle button', () => {
|
|
920
|
+
expect($menuBtn.attr('aria-disabled')).toBe('true');
|
|
921
|
+
});
|
|
922
|
+
|
|
923
|
+
test('THEN: sets aria-expanded="true" on the menu toggle button', () => {
|
|
924
|
+
expect($menuBtn.attr('aria-expanded')).toBe('true');
|
|
925
|
+
});
|
|
926
|
+
|
|
927
|
+
test('THEN: sets aria-controls to the correct menu ID', () => {
|
|
928
|
+
expect($menuBtn.attr('aria-controls')).toBe('menu-links-id');
|
|
929
|
+
});
|
|
930
|
+
});
|
|
931
|
+
|
|
932
|
+
describe('GIVEN: Progressive enhancement via JS', () => {
|
|
933
|
+
describe('WHEN: both menu and search toggles are present', () => {
|
|
934
|
+
let $, menuBtn, searchBtn, menuEl, searchEl;
|
|
935
|
+
|
|
936
|
+
beforeEach(() => {
|
|
937
|
+
$ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SEARCH_AND_MENU_LINKS));
|
|
938
|
+
document.body.innerHTML = $.html();
|
|
939
|
+
|
|
940
|
+
menuBtn = document.querySelector('.ons-js-toggle-nav-menu');
|
|
941
|
+
menuEl = document.querySelector('.ons-js-nav-menu');
|
|
942
|
+
searchBtn = document.querySelector('.ons-js-toggle-header-search');
|
|
943
|
+
searchEl = document.querySelector('.ons-js-header-search');
|
|
944
|
+
|
|
945
|
+
if (menuBtn && menuEl) {
|
|
946
|
+
const navToggleMenu = new NavigationToggle(menuBtn, menuEl, 'ons-u-d-no');
|
|
947
|
+
navToggleMenu.registerEvents();
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
if (searchBtn && searchEl) {
|
|
951
|
+
const navToggleSearch = new NavigationToggle(searchBtn, searchEl, 'ons-u-d-no');
|
|
952
|
+
navToggleSearch.registerEvents();
|
|
953
|
+
}
|
|
954
|
+
});
|
|
955
|
+
|
|
956
|
+
test('THEN: menu toggle is active (aria-disabled false, no disabled class)', () => {
|
|
957
|
+
expect(menuBtn).not.toBeNull();
|
|
958
|
+
expect(menuBtn.getAttribute('aria-disabled')).toBe('false');
|
|
959
|
+
expect(menuBtn.classList.contains('disabled')).toBe(false);
|
|
960
|
+
});
|
|
961
|
+
|
|
962
|
+
test('THEN: search toggle is active (aria-disabled false, no disabled class)', () => {
|
|
963
|
+
expect(searchBtn).not.toBeNull();
|
|
964
|
+
expect(searchBtn.getAttribute('aria-disabled')).toBe('false');
|
|
965
|
+
expect(searchBtn.classList.contains('disabled')).toBe(false);
|
|
966
|
+
});
|
|
967
|
+
|
|
968
|
+
test('WHEN: clicking menu toggle closes search if open', () => {
|
|
969
|
+
expect(menuBtn && searchBtn).not.toBeNull();
|
|
970
|
+
|
|
971
|
+
// open search followed by menu
|
|
972
|
+
searchBtn.click();
|
|
973
|
+
menuBtn.click();
|
|
974
|
+
|
|
975
|
+
expect(searchBtn.classList.contains('active')).toBe(false);
|
|
976
|
+
expect(searchEl.getAttribute('aria-hidden')).toBe('true');
|
|
977
|
+
expect(searchEl.classList.contains('ons-u-d-no')).toBe(true);
|
|
978
|
+
});
|
|
979
|
+
|
|
980
|
+
test('WHEN: clicking search toggle closes menu if open', () => {
|
|
981
|
+
expect(menuBtn && searchBtn).not.toBeNull();
|
|
982
|
+
|
|
983
|
+
// open menu followed by search
|
|
984
|
+
menuBtn.click();
|
|
985
|
+
searchBtn.click();
|
|
986
|
+
|
|
987
|
+
expect(menuBtn.classList.contains('active')).toBe(false);
|
|
988
|
+
expect(menuEl.getAttribute('aria-hidden')).toBe('true');
|
|
989
|
+
expect(menuEl.classList.contains('ons-u-d-no')).toBe(true);
|
|
990
|
+
});
|
|
991
|
+
});
|
|
992
|
+
});
|
|
883
993
|
});
|
|
884
994
|
});
|