@ons/design-system 53.1.1 → 55.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.
- package/components/accordion/_macro.njk +2 -3
- package/components/accordion/_macro.spec.js +3 -40
- package/components/accordion/accordion.dom.js +19 -0
- package/components/{collapsible/collapsible.group.js → accordion/accordion.js} +12 -5
- package/components/accordion/accordion.spec.js +56 -51
- package/components/autosuggest/_autosuggest.scss +4 -4
- package/components/autosuggest/autosuggest.spec.js +12 -2
- package/components/autosuggest/autosuggest.ui.js +4 -7
- package/components/button/_button.scss +28 -7
- package/components/button/_macro.njk +1 -1
- package/components/button/_macro.spec.js +2 -2
- package/components/checkboxes/_checkbox.scss +50 -17
- package/components/collapsible/_collapsible.scss +59 -85
- package/components/collapsible/_macro.njk +6 -39
- package/components/collapsible/_macro.spec.js +0 -53
- package/components/collapsible/collapsible.dom.js +3 -12
- package/components/collapsible/collapsible.js +3 -45
- package/components/collapsible/collapsible.spec.js +6 -139
- package/components/cookies-banner/_cookies-banner.scss +15 -7
- package/components/cookies-banner/_macro.njk +66 -22
- package/components/cookies-banner/_macro.spec.js +172 -114
- package/components/cookies-banner/cookies-banner.js +35 -13
- package/components/cookies-banner/cookies-banner.spec.js +58 -54
- package/components/document-list/document-list.scss +2 -0
- package/components/download-resources/download-resources.js +19 -0
- package/components/download-resources/download-resources.spec.js +95 -0
- package/components/external-link/_macro.njk +1 -1
- package/components/external-link/_macro.spec.js +2 -2
- package/components/fieldset/_fieldset.scss +11 -1
- package/components/fieldset/_macro.njk +9 -8
- package/components/fieldset/_macro.spec.js +27 -5
- package/components/footer/_footer.scss +1 -0
- package/components/header/_macro.njk +2 -5
- package/components/header/_macro.spec.js +0 -16
- package/components/hero/_macro.njk +1 -1
- package/components/hero/_macro.spec.js +1 -1
- package/components/icons/_macro.njk +1 -1
- package/components/input/_input-type.scss +37 -3
- package/components/input/_input.scss +28 -9
- package/components/input/_macro.njk +17 -14
- package/components/input/_macro.spec.js +56 -0
- package/components/label/_label.scss +1 -1
- package/components/label/_macro.njk +27 -15
- package/components/label/_macro.spec.js +31 -0
- package/components/lists/_macro.njk +1 -1
- package/components/lists/_macro.spec.js +2 -2
- package/components/message/_message.scss +1 -0
- package/components/modal/_macro.njk +2 -2
- package/components/modal/_modal.scss +10 -9
- package/components/mutually-exclusive/mutually-exclusive.duration.spec.js +2 -0
- package/components/mutually-exclusive/mutually-exclusive.number.spec.js +1 -0
- package/components/navigation/_macro.njk +0 -1
- package/components/navigation/_macro.spec.js +0 -1
- package/components/pagination/_pagination.scss +1 -0
- package/components/panel/_macro.njk +6 -7
- package/components/panel/_macro.spec.js +23 -20
- package/components/panel/_panel.scss +13 -5
- package/components/phase-banner/_phase-banner.scss +1 -0
- package/components/radios/_radio.scss +16 -4
- package/components/relationships/_relationships.scss +2 -2
- package/components/reply/_macro.njk +2 -2
- package/components/skip-to-content/_skip.scss +2 -1
- package/components/table/_macro.njk +3 -2
- package/components/table/_macro.spec.js +0 -27
- package/components/table/_table.scss +15 -7
- package/components/table/sortable-table.js +1 -0
- package/components/tabs/_tabs.scss +57 -34
- package/components/tabs/tabs.js +4 -2
- package/components/upload/_upload.scss +2 -2
- package/css/census.css +1 -1
- package/css/ids.css +1 -1
- package/css/main.css +1 -1
- package/js/main.js +1 -0
- package/layout/_template.njk +8 -8
- package/package.json +1 -1
- package/scripts/main.es5.js +1 -1
- package/scripts/main.js +2 -2
- package/scss/base/_global.scss +1 -0
- package/scss/objects/_page.scss +1 -1
- package/scss/overrides/hcm.scss +205 -46
- package/scss/patternlib.scss +1 -56
- package/scss/vars/_colors.scss +2 -1
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
onsButton({
|
|
16
16
|
"type": "button",
|
|
17
17
|
"text": params.allButton.open,
|
|
18
|
-
"classes": "ons-js-
|
|
18
|
+
"classes": "ons-js-accordion-all ons-u-mb-s ons-u-d-no",
|
|
19
19
|
"variants": ["secondary", "small"],
|
|
20
|
-
"innerClasses": "ons-js-
|
|
20
|
+
"innerClasses": "ons-js-accordion-all-inner",
|
|
21
21
|
"attributes": attributes
|
|
22
22
|
})
|
|
23
23
|
}}
|
|
@@ -36,7 +36,6 @@
|
|
|
36
36
|
"content": item.content,
|
|
37
37
|
"group": params.id,
|
|
38
38
|
"saveState": params.saveState,
|
|
39
|
-
"variants": params.variants,
|
|
40
39
|
"open": params.open
|
|
41
40
|
})
|
|
42
41
|
}}
|
|
@@ -54,18 +54,6 @@ describe('macro: accordion', () => {
|
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
describe('item', () => {
|
|
57
|
-
it('has provided variant style classes', () => {
|
|
58
|
-
const $ = cheerio.load(
|
|
59
|
-
renderComponent('accordion', {
|
|
60
|
-
...EXAMPLE_ACCORDION_WITH_TWO_ITEMS,
|
|
61
|
-
variants: ['variant-a', 'variant-b'],
|
|
62
|
-
}),
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
expect($('.ons-collapsible--variant-a').length).toBe(2);
|
|
66
|
-
expect($('.ons-collapsible--variant-b').length).toBe(2);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
57
|
it('has provided title text', () => {
|
|
70
58
|
const $ = cheerio.load(renderComponent('accordion', EXAMPLE_ACCORDION_WITH_TWO_ITEMS));
|
|
71
59
|
|
|
@@ -103,31 +91,6 @@ describe('macro: accordion', () => {
|
|
|
103
91
|
expect(titleText).toBe('Content for item 1');
|
|
104
92
|
});
|
|
105
93
|
|
|
106
|
-
it('outputs a button with the expected class', () => {
|
|
107
|
-
const $ = cheerio.load(
|
|
108
|
-
renderComponent('accordion', {
|
|
109
|
-
itemsList: [
|
|
110
|
-
{
|
|
111
|
-
title: 'Title for item 1',
|
|
112
|
-
button: {
|
|
113
|
-
open: 'Open label',
|
|
114
|
-
close: 'Close label',
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
title: 'Title for item 2',
|
|
119
|
-
button: {
|
|
120
|
-
open: 'Open label',
|
|
121
|
-
close: 'Close label',
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
],
|
|
125
|
-
}),
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
expect($('button.ons-js-collapsible-button').length).toBe(2);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
94
|
it('has additionally provided `attributes`', () => {
|
|
132
95
|
const $ = cheerio.load(
|
|
133
96
|
renderComponent('accordion', {
|
|
@@ -199,7 +162,7 @@ describe('macro: accordion', () => {
|
|
|
199
162
|
}),
|
|
200
163
|
);
|
|
201
164
|
|
|
202
|
-
expect($('button.ons-js-
|
|
165
|
+
expect($('button.ons-js-accordion-all').length).toBe(1);
|
|
203
166
|
});
|
|
204
167
|
|
|
205
168
|
it('has additionally provided `attributes`', () => {
|
|
@@ -217,8 +180,8 @@ describe('macro: accordion', () => {
|
|
|
217
180
|
}),
|
|
218
181
|
);
|
|
219
182
|
|
|
220
|
-
expect($('button.ons-js-
|
|
221
|
-
expect($('button.ons-js-
|
|
183
|
+
expect($('button.ons-js-accordion-all').attr('a')).toBe('123');
|
|
184
|
+
expect($('button.ons-js-accordion-all').attr('b')).toBe('456');
|
|
222
185
|
});
|
|
223
186
|
});
|
|
224
187
|
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import domready from '../../js/domready';
|
|
2
|
+
|
|
3
|
+
async function initialiseAccordions() {
|
|
4
|
+
const toggleAllButtons = [...document.querySelectorAll('.ons-js-accordion-all')];
|
|
5
|
+
|
|
6
|
+
if (toggleAllButtons.length) {
|
|
7
|
+
const collapsibleComponents = [...document.querySelectorAll('.ons-js-collapsible')];
|
|
8
|
+
|
|
9
|
+
const Collapsible = (await import('../collapsible/collapsible')).default;
|
|
10
|
+
const Accordion = (await import('./accordion')).default;
|
|
11
|
+
const collapsibles = collapsibleComponents.map(element => new Collapsible(element));
|
|
12
|
+
|
|
13
|
+
toggleAllButtons.forEach(button => {
|
|
14
|
+
new Accordion(button, collapsibles);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
domready(initialiseAccordions);
|
|
@@ -1,23 +1,28 @@
|
|
|
1
|
-
export default class
|
|
1
|
+
export default class Accordion {
|
|
2
2
|
constructor(button, collapsibles) {
|
|
3
3
|
this.openCollapsibles = 0;
|
|
4
4
|
|
|
5
5
|
this.button = button;
|
|
6
|
-
this.buttonInner = button.querySelector('.ons-js-
|
|
6
|
+
this.buttonInner = button.querySelector('.ons-js-accordion-all-inner');
|
|
7
7
|
this.group = button.getAttribute('data-group');
|
|
8
8
|
this.collapsibles = collapsibles.filter(collapsible => collapsible.group === this.group);
|
|
9
|
-
|
|
10
9
|
this.totalCollapsibles = this.collapsibles.length;
|
|
11
|
-
this.
|
|
10
|
+
this.buttonOpenEl = this.buttonInner.querySelector('.ons-btn__text');
|
|
11
|
+
this.buttonOpen = this.buttonOpenEl.innerHTML.trim();
|
|
12
12
|
this.closeButton = button.getAttribute('data-close-all');
|
|
13
|
+
this.open = this.collapsibles.find(collapsible => collapsible.open === true);
|
|
13
14
|
|
|
14
15
|
this.collapsibles.forEach(collapsible => {
|
|
15
16
|
collapsible.onOpen = this.onOpen.bind(this);
|
|
16
17
|
collapsible.onClose = this.onClose.bind(this);
|
|
17
18
|
});
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
if (this.open) {
|
|
21
|
+
this.openCollapsibles = this.totalCollapsibles;
|
|
22
|
+
}
|
|
20
23
|
|
|
24
|
+
this.button.addEventListener('click', this.handleButtonClick.bind(this));
|
|
25
|
+
this.setButton();
|
|
21
26
|
this.button.classList.remove('ons-u-d-no');
|
|
22
27
|
}
|
|
23
28
|
|
|
@@ -49,9 +54,11 @@ export default class CollapsibleGroup {
|
|
|
49
54
|
if (this.canClose()) {
|
|
50
55
|
this.buttonInner.innerHTML = this.closeButton;
|
|
51
56
|
this.button.setAttribute('data-ga-label', this.buttonOpen);
|
|
57
|
+
this.button.setAttribute('aria-expanded', 'true');
|
|
52
58
|
} else {
|
|
53
59
|
this.buttonInner.innerHTML = this.buttonOpen;
|
|
54
60
|
this.button.setAttribute('data-ga-label', this.closeButton);
|
|
61
|
+
this.button.setAttribute('aria-expanded', 'false');
|
|
55
62
|
}
|
|
56
63
|
}
|
|
57
64
|
}
|
|
@@ -6,26 +6,14 @@ const EXAMPLE_ACCORDION_WITH_THREE_ITEMS = {
|
|
|
6
6
|
{
|
|
7
7
|
title: 'Title for item 1',
|
|
8
8
|
content: 'Content for item 1',
|
|
9
|
-
button: {
|
|
10
|
-
open: 'Open item',
|
|
11
|
-
close: 'Close item',
|
|
12
|
-
},
|
|
13
9
|
},
|
|
14
10
|
{
|
|
15
11
|
title: 'Title for item 2',
|
|
16
12
|
content: 'Content for item 2',
|
|
17
|
-
button: {
|
|
18
|
-
open: 'Open item',
|
|
19
|
-
close: 'Close item',
|
|
20
|
-
},
|
|
21
13
|
},
|
|
22
14
|
{
|
|
23
15
|
title: 'Title for item 3',
|
|
24
16
|
content: 'Content for item 3',
|
|
25
|
-
button: {
|
|
26
|
-
open: 'Open item',
|
|
27
|
-
close: 'Close item',
|
|
28
|
-
},
|
|
29
17
|
},
|
|
30
18
|
],
|
|
31
19
|
};
|
|
@@ -42,43 +30,68 @@ const EXAMPLE_ACCORDION_WITH_ALL_BUTTON = {
|
|
|
42
30
|
};
|
|
43
31
|
|
|
44
32
|
describe('script: accordion', () => {
|
|
45
|
-
it('begins with all items
|
|
46
|
-
await setTestPage(
|
|
33
|
+
it('begins with all items open when specified', async () => {
|
|
34
|
+
await setTestPage(
|
|
35
|
+
'/test',
|
|
36
|
+
renderComponent('accordion', {
|
|
37
|
+
...EXAMPLE_ACCORDION_WITH_THREE_ITEMS,
|
|
38
|
+
open: true,
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
47
41
|
|
|
48
|
-
const
|
|
49
|
-
expect(
|
|
42
|
+
const openElements = await page.$$eval('.ons-js-collapsible', nodes => nodes.filter(node => node.open));
|
|
43
|
+
expect(openElements[0]).not.toBe(undefined);
|
|
44
|
+
expect(openElements[1]).not.toBe(undefined);
|
|
45
|
+
expect(openElements[2]).not.toBe(undefined);
|
|
50
46
|
});
|
|
51
47
|
|
|
52
|
-
it('
|
|
48
|
+
it('sets toggle all button label to "Hide all" when open is specified', async () => {
|
|
53
49
|
await setTestPage(
|
|
54
50
|
'/test',
|
|
55
51
|
renderComponent('accordion', {
|
|
56
|
-
...
|
|
52
|
+
...EXAMPLE_ACCORDION_WITH_ALL_BUTTON,
|
|
53
|
+
open: true,
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const buttonText = await page.$eval('button[data-test-trigger]', element => element.innerText);
|
|
58
|
+
expect(buttonText.trim()).toBe('Close all');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('sets toggle all button aria-expanded set to true when open is specified', async () => {
|
|
62
|
+
await setTestPage(
|
|
63
|
+
'/test',
|
|
64
|
+
renderComponent('accordion', {
|
|
65
|
+
...EXAMPLE_ACCORDION_WITH_ALL_BUTTON,
|
|
57
66
|
open: true,
|
|
58
67
|
}),
|
|
59
68
|
);
|
|
60
69
|
|
|
61
|
-
const
|
|
62
|
-
expect(
|
|
70
|
+
const ariaExpanded = await page.$eval('button[data-test-trigger]', element => element.getAttribute('aria-expanded'));
|
|
71
|
+
expect(ariaExpanded).toBe('true');
|
|
63
72
|
});
|
|
64
73
|
|
|
65
|
-
it('opens all items when accordion
|
|
74
|
+
it('opens all items when accordion `allbutton` is clicked', async () => {
|
|
66
75
|
await setTestPage('/test', renderComponent('accordion', EXAMPLE_ACCORDION_WITH_ALL_BUTTON));
|
|
67
76
|
|
|
68
77
|
await page.click('button[data-test-trigger]');
|
|
69
78
|
|
|
70
|
-
const
|
|
71
|
-
expect(
|
|
79
|
+
const openElements = await page.$$eval('.ons-js-collapsible', nodes => nodes.filter(node => node.open));
|
|
80
|
+
expect(openElements[0]).not.toBe(undefined);
|
|
81
|
+
expect(openElements[1]).not.toBe(undefined);
|
|
82
|
+
expect(openElements[2]).not.toBe(undefined);
|
|
72
83
|
});
|
|
73
84
|
|
|
74
|
-
it('closes all items when accordion
|
|
85
|
+
it('closes all items when accordion `allbutton` is clicked twice', async () => {
|
|
75
86
|
await setTestPage('/test', renderComponent('accordion', EXAMPLE_ACCORDION_WITH_ALL_BUTTON));
|
|
76
87
|
|
|
77
88
|
await page.click('button[data-test-trigger]');
|
|
78
89
|
await page.click('button[data-test-trigger]');
|
|
79
90
|
|
|
80
|
-
const
|
|
81
|
-
expect(
|
|
91
|
+
const openElements = await page.$$eval('.ons-js-collapsible', nodes => nodes.filter(node => node.open));
|
|
92
|
+
expect(openElements[0]).toBe(undefined);
|
|
93
|
+
expect(openElements[1]).toBe(undefined);
|
|
94
|
+
expect(openElements[2]).toBe(undefined);
|
|
82
95
|
});
|
|
83
96
|
|
|
84
97
|
it('starts with the toggle all button labelled as "Open all"', async () => {
|
|
@@ -88,47 +101,39 @@ describe('script: accordion', () => {
|
|
|
88
101
|
expect(buttonText.trim()).toBe('Open all');
|
|
89
102
|
});
|
|
90
103
|
|
|
91
|
-
it('
|
|
104
|
+
it('starts with the toggle all button aria-expanded set to false', async () => {
|
|
92
105
|
await setTestPage('/test', renderComponent('accordion', EXAMPLE_ACCORDION_WITH_ALL_BUTTON));
|
|
93
106
|
|
|
94
|
-
await page
|
|
95
|
-
|
|
96
|
-
const buttonText = await page.$eval('button[data-test-trigger]', element => element.innerText);
|
|
97
|
-
expect(buttonText.trim()).toBe('Close all');
|
|
107
|
+
const ariaExpanded = await page.$eval('button[data-test-trigger]', element => element.getAttribute('aria-expanded'));
|
|
108
|
+
expect(ariaExpanded).toBe('false');
|
|
98
109
|
});
|
|
99
110
|
|
|
100
|
-
it('sets toggle all button label to "Hide all" when
|
|
111
|
+
it('sets toggle all button label to "Hide all" when clicked', async () => {
|
|
101
112
|
await setTestPage('/test', renderComponent('accordion', EXAMPLE_ACCORDION_WITH_ALL_BUTTON));
|
|
102
113
|
|
|
103
|
-
await page.click('
|
|
104
|
-
await page.click('#example-accordion-2 .ons-collapsible__btn');
|
|
105
|
-
await page.click('#example-accordion-3 .ons-collapsible__btn');
|
|
114
|
+
await page.click('button[data-test-trigger]');
|
|
106
115
|
|
|
107
116
|
const buttonText = await page.$eval('button[data-test-trigger]', element => element.innerText);
|
|
108
117
|
expect(buttonText.trim()).toBe('Close all');
|
|
109
118
|
});
|
|
110
119
|
|
|
111
|
-
it('
|
|
112
|
-
await setTestPage('/test', renderComponent('accordion',
|
|
120
|
+
it('sets toggle all button aria-expanded set to true when clicked', async () => {
|
|
121
|
+
await setTestPage('/test', renderComponent('accordion', EXAMPLE_ACCORDION_WITH_ALL_BUTTON));
|
|
113
122
|
|
|
114
|
-
await page.click('
|
|
115
|
-
await page.click('#example-accordion-3 .ons-collapsible__btn');
|
|
123
|
+
await page.click('button[data-test-trigger]');
|
|
116
124
|
|
|
117
|
-
const
|
|
118
|
-
expect(
|
|
125
|
+
const ariaExpanded = await page.$eval('button[data-test-trigger]', element => element.getAttribute('aria-expanded'));
|
|
126
|
+
expect(ariaExpanded).toBe('true');
|
|
119
127
|
});
|
|
120
128
|
|
|
121
|
-
it('
|
|
122
|
-
await setTestPage('/test', renderComponent('accordion',
|
|
123
|
-
|
|
124
|
-
await page.click('#example-accordion-2 .ons-collapsible__btn');
|
|
125
|
-
await page.click('#example-accordion-3 .ons-collapsible__btn');
|
|
126
|
-
await page.click('#example-accordion-3 .ons-collapsible__btn');
|
|
129
|
+
it('sets toggle all button label to "Hide all" when all items are shown', async () => {
|
|
130
|
+
await setTestPage('/test', renderComponent('accordion', EXAMPLE_ACCORDION_WITH_ALL_BUTTON));
|
|
127
131
|
|
|
128
|
-
|
|
129
|
-
|
|
132
|
+
await page.click('#example-accordion-1 .ons-collapsible__heading');
|
|
133
|
+
await page.click('#example-accordion-2 .ons-collapsible__heading');
|
|
134
|
+
await page.click('#example-accordion-3 .ons-collapsible__heading');
|
|
130
135
|
|
|
131
|
-
const
|
|
132
|
-
expect(
|
|
136
|
+
const buttonText = await page.$eval('button[data-test-trigger]', element => element.innerText);
|
|
137
|
+
expect(buttonText.trim()).toBe('Close all');
|
|
133
138
|
});
|
|
134
139
|
});
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
&__results {
|
|
14
|
-
border: 1px solid $color-input;
|
|
14
|
+
border: 1px solid $color-input-border;
|
|
15
15
|
border-radius: $input-radius;
|
|
16
16
|
display: none;
|
|
17
17
|
margin: 0.5rem 0 0;
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
&__results-title {
|
|
29
29
|
background: $color-grey-15;
|
|
30
|
-
border-bottom: 1px solid $color-input;
|
|
30
|
+
border-bottom: 1px solid $color-input-border;
|
|
31
31
|
padding: 0.25rem 0.5rem;
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
padding: $input-padding-horizontal;
|
|
49
49
|
|
|
50
50
|
&:not(:last-child) {
|
|
51
|
-
border-bottom: 1px solid $color-input;
|
|
51
|
+
border-bottom: 1px solid $color-input-border;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
&:not(&--no-results):not(&--more-results):hover,
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
padding-left: 0.5rem;
|
|
88
88
|
|
|
89
89
|
&:not(:last-child) {
|
|
90
|
-
border-bottom: 1px solid $color-input;
|
|
90
|
+
border-bottom: 1px solid $color-input-border;
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -118,6 +118,16 @@ describe('script: autosuggest', () => {
|
|
|
118
118
|
expect(ariaActiveDescendant).toBe(selectedOptionId);
|
|
119
119
|
});
|
|
120
120
|
|
|
121
|
+
it('sets aria status to a message showing the selected result', async () => {
|
|
122
|
+
await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
|
|
123
|
+
|
|
124
|
+
await page.type('.ons-js-autosuggest-input', 'Eng', { delay: 20 });
|
|
125
|
+
await page.keyboard.press('ArrowDown');
|
|
126
|
+
|
|
127
|
+
const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', node => node.textContent);
|
|
128
|
+
expect(statusMessage.trim()).toBe('England');
|
|
129
|
+
});
|
|
130
|
+
|
|
121
131
|
it('does not mark other suggestions as being selected', async () => {
|
|
122
132
|
await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
|
|
123
133
|
|
|
@@ -297,7 +307,7 @@ describe('script: autosuggest', () => {
|
|
|
297
307
|
|
|
298
308
|
const attributes = await getNodeAttributes(page, '.ons-js-autosuggest-input');
|
|
299
309
|
expect(attributes['aria-activedescendant']).toBeUndefined();
|
|
300
|
-
expect(attributes['aria-expanded']).
|
|
310
|
+
expect(attributes['aria-expanded']).toBe('false');
|
|
301
311
|
});
|
|
302
312
|
});
|
|
303
313
|
|
|
@@ -502,7 +512,7 @@ describe('script: autosuggest', () => {
|
|
|
502
512
|
await page.type('.ons-js-autosuggest-input', 'abc', { delay: 20 });
|
|
503
513
|
|
|
504
514
|
const ariaExpandedValue = await page.$eval('.ons-js-autosuggest-input', node => node.getAttribute('aria-expanded'));
|
|
505
|
-
expect(ariaExpandedValue).toBe(
|
|
515
|
+
expect(ariaExpandedValue).toBe('false');
|
|
506
516
|
});
|
|
507
517
|
});
|
|
508
518
|
});
|
|
@@ -322,7 +322,7 @@ export default class AutosuggestUI {
|
|
|
322
322
|
this.listbox.innerHTML = '';
|
|
323
323
|
this.context.classList.remove(classAutosuggestHasResults);
|
|
324
324
|
this.input.removeAttribute('aria-activedescendant');
|
|
325
|
-
this.input.
|
|
325
|
+
this.input.setAttribute('aria-expanded', false);
|
|
326
326
|
|
|
327
327
|
if (!preventAriaStatusUpdate) {
|
|
328
328
|
this.setAriaStatus();
|
|
@@ -343,15 +343,12 @@ export default class AutosuggestUI {
|
|
|
343
343
|
this.listbox.innerHTML = '';
|
|
344
344
|
if (this.results) {
|
|
345
345
|
this.resultOptions = this.results.map((result, index) => {
|
|
346
|
-
let ariaLabel = result[this.lang];
|
|
347
|
-
ariaLabel = ariaLabel.split('(<span class="ons-autosuggest-input__group">')[0];
|
|
348
346
|
let innerHTML = this.emboldenMatch(result[this.lang], this.query);
|
|
349
347
|
|
|
350
348
|
const listElement = document.createElement('li');
|
|
351
349
|
listElement.className = classAutosuggestOption;
|
|
352
350
|
listElement.setAttribute('id', `${this.listboxId}__option--${index}`);
|
|
353
351
|
listElement.setAttribute('role', 'option');
|
|
354
|
-
listElement.setAttribute('aria-label', ariaLabel);
|
|
355
352
|
if (result.category) {
|
|
356
353
|
innerHTML =
|
|
357
354
|
innerHTML + `<span class="ons-autosuggest-input__category ons-u-lighter ons-u-fs-s ons-u-db">${result.category}</span>`;
|
|
@@ -437,13 +434,13 @@ export default class AutosuggestUI {
|
|
|
437
434
|
option.setAttribute('aria-selected', true);
|
|
438
435
|
this.input.setAttribute('aria-activedescendant', option.getAttribute('id'));
|
|
439
436
|
const groupedResult = option.querySelector('.ons-autosuggest-input__group');
|
|
440
|
-
const
|
|
437
|
+
const optionText = option.innerHTML.replace('<strong>', '').replace('</strong>', '');
|
|
441
438
|
if (groupedResult) {
|
|
442
439
|
let groupedAriaMsg = this.ariaGroupedResults.replace('{n}', groupedResult.innerHTML);
|
|
443
|
-
groupedAriaMsg = groupedAriaMsg.replace('{x}',
|
|
440
|
+
groupedAriaMsg = groupedAriaMsg.replace('{x}', optionText);
|
|
444
441
|
this.setAriaStatus(groupedAriaMsg);
|
|
445
442
|
} else {
|
|
446
|
-
this.setAriaStatus(
|
|
443
|
+
this.setAriaStatus(optionText);
|
|
447
444
|
}
|
|
448
445
|
} else {
|
|
449
446
|
option.classList.remove(classAutosuggestOptionFocused);
|
|
@@ -63,8 +63,11 @@ $button-shadow-size: 3px;
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
// When focused
|
|
66
|
-
&:focus
|
|
66
|
+
&:focus,
|
|
67
|
+
&:focus-visible {
|
|
68
|
+
// Add transparent outline because Windows High Contrast Mode doesn't show box-shadows
|
|
67
69
|
outline: 3px solid transparent;
|
|
70
|
+
outline-offset: 1px;
|
|
68
71
|
}
|
|
69
72
|
|
|
70
73
|
&:focus &__inner {
|
|
@@ -91,11 +94,6 @@ $button-shadow-size: 3px;
|
|
|
91
94
|
top: ems($button-shadow-size);
|
|
92
95
|
}
|
|
93
96
|
|
|
94
|
-
&:focus,
|
|
95
|
-
&:focus:hover {
|
|
96
|
-
outline: none;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
97
|
// Small buttons
|
|
100
98
|
&--small,
|
|
101
99
|
&--mobile {
|
|
@@ -170,6 +168,8 @@ $button-shadow-size: 3px;
|
|
|
170
168
|
|
|
171
169
|
&--link:focus:not(:active):not(&--secondary) &,
|
|
172
170
|
&--link:focus:hover:not(:active):not(&--secondary) & {
|
|
171
|
+
outline: inherit;
|
|
172
|
+
|
|
173
173
|
&__inner {
|
|
174
174
|
.ons-svg-icon {
|
|
175
175
|
fill: $color-text;
|
|
@@ -386,13 +386,20 @@ $button-shadow-size: 3px;
|
|
|
386
386
|
&--ghost-dark:focus &,
|
|
387
387
|
&--dropdown:focus & {
|
|
388
388
|
&__inner {
|
|
389
|
-
|
|
389
|
+
border-color: $color-text-link-focus;
|
|
390
|
+
box-shadow: 0 0 0 1px $color-text-link-focus;
|
|
390
391
|
.ons-svg-icon {
|
|
391
392
|
fill: $color-black;
|
|
392
393
|
}
|
|
393
394
|
}
|
|
394
395
|
}
|
|
395
396
|
|
|
397
|
+
&--dropdown:focus & {
|
|
398
|
+
&__inner {
|
|
399
|
+
box-shadow: inset 0 -4px 0 0 $color-text-link-focus;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
396
403
|
&--mobile[aria-expanded='true'],
|
|
397
404
|
&--text-link[aria-expanded='true'] {
|
|
398
405
|
.ons-svg-icon {
|
|
@@ -473,3 +480,17 @@ $button-shadow-size: 3px;
|
|
|
473
480
|
}
|
|
474
481
|
}
|
|
475
482
|
}
|
|
483
|
+
|
|
484
|
+
.ons-btn-group {
|
|
485
|
+
@extend .ons-u-mb-m;
|
|
486
|
+
|
|
487
|
+
align-items: baseline;
|
|
488
|
+
display: flex;
|
|
489
|
+
flex-direction: row;
|
|
490
|
+
flex-wrap: wrap;
|
|
491
|
+
|
|
492
|
+
& .ons-btn,
|
|
493
|
+
& a {
|
|
494
|
+
margin: 0 1rem 1rem 0;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
{% endif -%}
|
|
87
87
|
</span>
|
|
88
88
|
{% if params.url is defined and params.url and params.newWindow is defined and params.newWindow %}
|
|
89
|
-
<span class="ons-btn__new-window-description ons-u-vh">({{ params.newWindowDescription | default("opens in a new tab") }})</span>
|
|
89
|
+
<span class="ons-btn__new-window-description ons-u-vh"> ({{ params.newWindowDescription | default("opens in a new tab") }})</span>
|
|
90
90
|
{% endif %}
|
|
91
91
|
{% if params.buttonContext is defined and params.buttonContext %}
|
|
92
92
|
<span class="ons-btn__context ons-u-vh">{{ params.buttonContext }}</span>
|
|
@@ -407,7 +407,7 @@ describe('macro: button', () => {
|
|
|
407
407
|
}),
|
|
408
408
|
);
|
|
409
409
|
|
|
410
|
-
expect($('.ons-btn__new-window-description').text()).toBe('(opens in a new tab)');
|
|
410
|
+
expect($('.ons-btn__new-window-description').text()).toBe(' (opens in a new tab)');
|
|
411
411
|
});
|
|
412
412
|
|
|
413
413
|
it('has a custom new window description when `newWindow` is `true` and `newWindowDescription` is provided', () => {
|
|
@@ -419,7 +419,7 @@ describe('macro: button', () => {
|
|
|
419
419
|
}),
|
|
420
420
|
);
|
|
421
421
|
|
|
422
|
-
expect($('.ons-btn__new-window-description').text()).toBe('(custom opens in a new window text)');
|
|
422
|
+
expect($('.ons-btn__new-window-description').text()).toBe(' (custom opens in a new window text)');
|
|
423
423
|
});
|
|
424
424
|
|
|
425
425
|
it('has the `download` attribute when `buttonStyle` is "download"', () => {
|