@ons/design-system 60.0.3 → 61.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/components/access-code/_macro.njk +6 -8
- package/components/accordion/_macro.njk +2 -3
- package/components/accordion/_macro.spec.js +9 -9
- package/components/accordion/accordion.dom.js +4 -4
- package/components/accordion/accordion.js +14 -14
- package/components/accordion/accordion.spec.js +6 -6
- package/components/collapsible/_macro.njk +20 -28
- package/components/collapsible/_macro.spec.js +15 -15
- package/components/{collapsible/_collapsible.scss → details/_details.scss} +14 -14
- package/components/details/_macro.njk +30 -0
- package/components/details/_macro.spec.js +151 -0
- package/components/details/details.dom.js +13 -0
- package/components/details/details.js +66 -0
- package/components/details/details.spec.js +103 -0
- package/components/hero/_hero.scss +2 -2
- package/components/modal/modal.js +12 -6
- package/components/modal/modal.spec.js +0 -11
- package/components/question/_macro.njk +4 -4
- package/components/question/_macro.spec.js +14 -14
- package/components/summary/_macro.njk +1 -1
- package/components/summary/_macro.spec.js +148 -1
- package/components/summary/_summary.scss +6 -2
- package/components/table/_macro.spec.js +10 -8
- package/components/timeout-modal/_macro.njk +19 -20
- package/components/timeout-modal/timeout-modal.spec.js +17 -13
- package/components/video/_macro.njk +18 -4
- package/components/video/_macro.spec.js +46 -33
- package/components/video/_video.scss +4 -0
- package/components/video/video.dom.js +13 -0
- package/components/video/video.js +30 -0
- package/components/video/video.spec.js +72 -0
- package/css/main.css +3 -3
- package/css/print.css +1 -1
- package/js/analytics.js +1 -5
- package/js/main.js +2 -1
- package/js/timeout.js +7 -0
- package/package.json +2 -1
- package/scripts/main.es5.js +1 -1
- package/scripts/main.js +1 -1
- package/scss/main.scss +1 -1
- package/scss/objects/_page.scss +1 -1
- package/scss/objects/_spacing.scss +1 -1
- package/scss/overrides/hcm.scss +1 -1
- package/scss/print.scss +1 -1
- package/components/collapsible/collapsible.dom.js +0 -13
- package/components/collapsible/collapsible.js +0 -66
- package/components/collapsible/collapsible.spec.js +0 -103
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export default class Details {
|
|
2
|
+
constructor(detailsElement) {
|
|
3
|
+
this.saveState = detailsElement.getAttribute('data-save-state') === 'true';
|
|
4
|
+
this.open = detailsElement.getAttribute('data-open') === 'true';
|
|
5
|
+
this.group = detailsElement.getAttribute('data-group');
|
|
6
|
+
|
|
7
|
+
// Elements
|
|
8
|
+
this.details = detailsElement;
|
|
9
|
+
this.detailsHeader = this.details.querySelector('.ons-js-details-heading');
|
|
10
|
+
|
|
11
|
+
// Initialise
|
|
12
|
+
const detailsId = detailsElement.getAttribute('id');
|
|
13
|
+
|
|
14
|
+
if (localStorage.getItem(detailsId) || this.open) {
|
|
15
|
+
this.setOpen(true);
|
|
16
|
+
this.details['setAttribute']('open', '');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
this.detailsHeader.addEventListener('click', this.toggle.bind(this));
|
|
20
|
+
this.detailsHeader.addEventListener('keydown', this.keyboardInteraction.bind(this));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
toggle(event) {
|
|
24
|
+
event.preventDefault();
|
|
25
|
+
this.setOpen(!this.isOpen);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
setOpen(open) {
|
|
29
|
+
if (open !== this.isOpen) {
|
|
30
|
+
const action = open ? 'Open' : 'Close';
|
|
31
|
+
const openAttribute = open ? 'set' : 'remove';
|
|
32
|
+
|
|
33
|
+
this.isOpen = open;
|
|
34
|
+
this.details[`${openAttribute}Attribute`]('open', '');
|
|
35
|
+
this.detailsHeader.setAttribute('data-ga-action', `${action} panel`);
|
|
36
|
+
|
|
37
|
+
if (this.onOpen && this.onClose) {
|
|
38
|
+
if (open) {
|
|
39
|
+
this.onOpen();
|
|
40
|
+
} else {
|
|
41
|
+
this.onClose();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (this.saveState === true && open === true) {
|
|
47
|
+
localStorage.setItem(this.details.getAttribute('id'), true);
|
|
48
|
+
} else {
|
|
49
|
+
localStorage.removeItem(this.details.getAttribute('id'));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
keyboardInteraction(event) {
|
|
54
|
+
const keyCode = event.which;
|
|
55
|
+
switch (keyCode) {
|
|
56
|
+
// Enter/Space
|
|
57
|
+
case 13:
|
|
58
|
+
case 32:
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
event.stopPropagation();
|
|
61
|
+
|
|
62
|
+
this.toggle(event);
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { renderComponent, setTestPage } from '../../tests/helpers/rendering';
|
|
2
|
+
|
|
3
|
+
const EXAMPLE_DETAILS_BASIC = {
|
|
4
|
+
id: 'details-id',
|
|
5
|
+
title: 'Title for details',
|
|
6
|
+
content: 'Content for details',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
describe('script: details', () => {
|
|
10
|
+
it('begins open when specified', async () => {
|
|
11
|
+
await setTestPage(
|
|
12
|
+
'/test',
|
|
13
|
+
renderComponent('details', {
|
|
14
|
+
...EXAMPLE_DETAILS_BASIC,
|
|
15
|
+
open: true,
|
|
16
|
+
}),
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const openAttribute = await page.$eval('.ons-js-details', node => node.open !== null);
|
|
20
|
+
expect(openAttribute).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('when the details heading is clicked to open the details', () => {
|
|
24
|
+
beforeEach(async () => {
|
|
25
|
+
await setTestPage('/test', renderComponent('details', EXAMPLE_DETAILS_BASIC));
|
|
26
|
+
await page.click('.ons-js-details-heading');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('sets the `open` attribute', async () => {
|
|
30
|
+
const openAttribute = await page.$eval('.ons-js-details', node => node.open !== null);
|
|
31
|
+
expect(openAttribute).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('sets the `ga` attributes', async () => {
|
|
35
|
+
const gaHeadingAttribute = await page.$eval('.ons-js-details-heading', element => element.getAttribute('data-ga-action'));
|
|
36
|
+
|
|
37
|
+
expect(gaHeadingAttribute).toBe('Open panel');
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('when the details heading is focused', () => {
|
|
42
|
+
beforeEach(async () => {
|
|
43
|
+
await setTestPage('/test', renderComponent('details', EXAMPLE_DETAILS_BASIC));
|
|
44
|
+
await page.focus('.ons-js-details-heading');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('when the space bar is pressed', () => {
|
|
48
|
+
beforeEach(async () => {
|
|
49
|
+
await page.keyboard.press('Space');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('opens the details content', async () => {
|
|
53
|
+
const openAttribute = await page.$eval('.ons-js-details', node => node.open !== null);
|
|
54
|
+
expect(openAttribute).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
describe('when the Enter key is pressed', () => {
|
|
59
|
+
beforeEach(async () => {
|
|
60
|
+
await page.keyboard.press('Enter');
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('opens the details content', async () => {
|
|
64
|
+
const openAttribute = await page.$eval('.ons-js-details', node => node.open !== null);
|
|
65
|
+
expect(openAttribute).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('when the state is set to save', () => {
|
|
71
|
+
beforeEach(async () => {
|
|
72
|
+
await setTestPage(
|
|
73
|
+
'/test',
|
|
74
|
+
renderComponent('details', {
|
|
75
|
+
...EXAMPLE_DETAILS_BASIC,
|
|
76
|
+
saveState: true,
|
|
77
|
+
}),
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('when the details is opened', () => {
|
|
82
|
+
beforeEach(async () => {
|
|
83
|
+
await page.click('.ons-js-details-heading');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('sets state in localStorage', async () => {
|
|
87
|
+
const localStorage = await page.evaluate(() => localStorage.getItem('details-id'));
|
|
88
|
+
expect(localStorage).toBe('true');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('when the details is closed', () => {
|
|
93
|
+
beforeEach(async () => {
|
|
94
|
+
await page.click('.ons-js-details-heading');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('removes state in localStorage', async () => {
|
|
98
|
+
const localStorage = await page.evaluate(() => localStorage.getItem('details-id'));
|
|
99
|
+
expect(localStorage).toBe(null);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
});
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
min-height: 300px;
|
|
17
17
|
position: relative;
|
|
18
18
|
|
|
19
|
-
&--has-
|
|
19
|
+
&--has-details {
|
|
20
20
|
align-items: flex-start; // Prevents undesired shift if not enough content
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
text-decoration-thickness: 2px;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
.ons-
|
|
62
|
+
.ons-details__heading {
|
|
63
63
|
color: inherit;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import dialogPolyfill from 'dialog-polyfill';
|
|
2
|
+
import initAnalytics from '../../js/analytics';
|
|
2
3
|
|
|
3
4
|
const overLayClass = 'ons-modal-overlay';
|
|
4
5
|
const ie11Class = 'ons-modal-ie11';
|
|
@@ -8,7 +9,7 @@ export default class Modal {
|
|
|
8
9
|
this.component = component;
|
|
9
10
|
this.launcher = document.querySelector(`[data-modal-id=${component.id}]`);
|
|
10
11
|
this.closeButton = component.querySelector('.ons-js-modal-btn');
|
|
11
|
-
this.
|
|
12
|
+
this.setGAAttributes = component.getAttribute('data-enable-ga');
|
|
12
13
|
this.lastFocusedEl = null;
|
|
13
14
|
this.dialogCSSSupported = true;
|
|
14
15
|
this.modalType = this.component.classList.contains('ons-js-timeout-modal') ? 'Timeout' : 'Generic';
|
|
@@ -33,9 +34,10 @@ export default class Modal {
|
|
|
33
34
|
if (this.modalType !== 'Timeout') {
|
|
34
35
|
window.addEventListener('keydown', this.escToClose.bind(this));
|
|
35
36
|
}
|
|
36
|
-
|
|
37
|
-
this.
|
|
38
|
-
|
|
37
|
+
|
|
38
|
+
if (this.setGAAttributes) {
|
|
39
|
+
this.component.setAttribute('data-ga', `visible`);
|
|
40
|
+
}
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
dialogSupported() {
|
|
@@ -71,13 +73,15 @@ export default class Modal {
|
|
|
71
73
|
this.component.showModal();
|
|
72
74
|
}
|
|
73
75
|
|
|
74
|
-
if (this.
|
|
76
|
+
if (this.setGAAttributes) {
|
|
75
77
|
if (event) {
|
|
76
78
|
this.component.setAttribute('data-ga-action', `Modal opened by ${event.type} event`);
|
|
77
79
|
} else {
|
|
78
80
|
this.component.setAttribute('data-ga-action', 'Modal opened by timed event');
|
|
79
81
|
}
|
|
80
82
|
this.component.setAttribute('data-ga-label', `${this.modalType} modal opened`);
|
|
83
|
+
this.component.setAttribute('data-ga-category', `${this.modalType} modal`);
|
|
84
|
+
initAnalytics();
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
87
|
}
|
|
@@ -116,13 +120,15 @@ export default class Modal {
|
|
|
116
120
|
this.component.close();
|
|
117
121
|
this.setFocusOnLastFocusedEl(this.lastFocusedEl);
|
|
118
122
|
|
|
119
|
-
if (this.
|
|
123
|
+
if (this.setGAAttributes) {
|
|
120
124
|
if (event) {
|
|
121
125
|
this.component.setAttribute('data-ga-action', `Modal closed by ${event.type} event`);
|
|
122
126
|
} else {
|
|
123
127
|
this.component.setAttribute('data-ga-action', 'Modal closed by timed event');
|
|
124
128
|
}
|
|
125
129
|
this.component.setAttribute('data-ga-label', `${this.modalType} modal closed`);
|
|
130
|
+
this.component.setAttribute('data-ga-category', `${this.modalType} modal`);
|
|
131
|
+
initAnalytics();
|
|
126
132
|
}
|
|
127
133
|
}
|
|
128
134
|
}
|
|
@@ -82,17 +82,6 @@ describe('script: modal', () => {
|
|
|
82
82
|
await setTestPage('/test', template);
|
|
83
83
|
});
|
|
84
84
|
|
|
85
|
-
describe('when the page has been loaded but the modal has not been opened yet', () => {
|
|
86
|
-
it('has the correct attributes set on the modal', async () => {
|
|
87
|
-
const gaLabel = await page.$eval('.ons-modal', node => node.getAttribute('data-ga-label'));
|
|
88
|
-
const gaAction = await page.$eval('.ons-modal', node => node.getAttribute('data-ga-action'));
|
|
89
|
-
const gaCategory = await page.$eval('.ons-modal', node => node.getAttribute('data-ga-category'));
|
|
90
|
-
expect(gaLabel).toBe('Generic modal initialised');
|
|
91
|
-
expect(gaAction).toBe('Modal initialised');
|
|
92
|
-
expect(gaCategory).toBe('Generic modal');
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
|
|
96
85
|
describe('when the modal is launched by a click event', () => {
|
|
97
86
|
beforeEach(async () => {
|
|
98
87
|
await page.focus('#launcher');
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
|
|
19
19
|
{% if params.definition %}
|
|
20
20
|
{% set questionDefinition %}
|
|
21
|
-
{% from "components/
|
|
22
|
-
{% call
|
|
21
|
+
{% from "components/details/_macro.njk" import onsDetails %}
|
|
22
|
+
{% call onsDetails({
|
|
23
23
|
"id": params.definition.id,
|
|
24
24
|
"classes": 'ons-u-mb-m',
|
|
25
25
|
"title": params.definition.title
|
|
@@ -109,8 +109,8 @@
|
|
|
109
109
|
{% endif %}
|
|
110
110
|
|
|
111
111
|
{% if params.justification %}
|
|
112
|
-
{% from "components/
|
|
113
|
-
{% call
|
|
112
|
+
{% from "components/details/_macro.njk" import onsDetails %}
|
|
113
|
+
{% call onsDetails({
|
|
114
114
|
"id": params.justification.id,
|
|
115
115
|
"classes": 'ons-u-mb-m',
|
|
116
116
|
"title": params.justification.title | default('Why we ask this question')
|
|
@@ -163,21 +163,21 @@ describe('macro: question', () => {
|
|
|
163
163
|
});
|
|
164
164
|
|
|
165
165
|
describe('mode: with definition', () => {
|
|
166
|
-
it('outputs the expected
|
|
166
|
+
it('outputs the expected details', () => {
|
|
167
167
|
const faker = templateFaker();
|
|
168
|
-
const
|
|
168
|
+
const detailsSpy = faker.spy('details');
|
|
169
169
|
|
|
170
170
|
faker.renderComponent('question', EXAMPLE_QUESTION_DEFINITION);
|
|
171
171
|
|
|
172
|
-
expect(
|
|
173
|
-
expect(
|
|
174
|
-
expect(
|
|
172
|
+
expect(detailsSpy.occurrences[0]).toHaveProperty('classes', 'ons-u-mb-m');
|
|
173
|
+
expect(detailsSpy.occurrences[0]).toHaveProperty('id', 'definition-id');
|
|
174
|
+
expect(detailsSpy.occurrences[0]).toHaveProperty('title', 'Definition title');
|
|
175
175
|
});
|
|
176
176
|
|
|
177
|
-
it('outputs the expected
|
|
177
|
+
it('outputs the expected details call content', () => {
|
|
178
178
|
const $ = cheerio.load(renderComponent('question', EXAMPLE_QUESTION_DEFINITION));
|
|
179
179
|
|
|
180
|
-
expect($('.ons-
|
|
180
|
+
expect($('.ons-details__content > p').text()).toBe('Definition content');
|
|
181
181
|
});
|
|
182
182
|
});
|
|
183
183
|
|
|
@@ -227,21 +227,21 @@ describe('macro: question', () => {
|
|
|
227
227
|
});
|
|
228
228
|
|
|
229
229
|
describe('mode: with justification', () => {
|
|
230
|
-
it('outputs the expected
|
|
230
|
+
it('outputs the expected details', () => {
|
|
231
231
|
const faker = templateFaker();
|
|
232
|
-
const
|
|
232
|
+
const detailsSpy = faker.spy('details');
|
|
233
233
|
|
|
234
234
|
faker.renderComponent('question', EXAMPLE_QUESTION_JUSTIFICATION);
|
|
235
235
|
|
|
236
|
-
expect(
|
|
237
|
-
expect(
|
|
238
|
-
expect(
|
|
236
|
+
expect(detailsSpy.occurrences[0]).toHaveProperty('classes', 'ons-u-mb-m');
|
|
237
|
+
expect(detailsSpy.occurrences[0]).toHaveProperty('id', 'justification-id');
|
|
238
|
+
expect(detailsSpy.occurrences[0]).toHaveProperty('title', 'Justification title');
|
|
239
239
|
});
|
|
240
240
|
|
|
241
|
-
it('outputs the expected
|
|
241
|
+
it('outputs the expected details call content', () => {
|
|
242
242
|
const $ = cheerio.load(renderComponent('question', EXAMPLE_QUESTION_JUSTIFICATION));
|
|
243
243
|
|
|
244
|
-
expect($('.ons-
|
|
244
|
+
expect($('.ons-details__content > p').text()).toBe('Justification content');
|
|
245
245
|
});
|
|
246
246
|
});
|
|
247
247
|
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
{% endif %}
|
|
113
113
|
|
|
114
114
|
{% if group.summaryLink %}
|
|
115
|
-
<div class="ons-summary__link{% if group.placeholderText or group.rows %} ons-u-pt-s{% endif %}{% if group.placeholderText is not defined and group.rows | length > 1 %} ons-u-bt{% endif %}">
|
|
115
|
+
<div class="ons-summary__link{% if group.placeholderText or group.rows %} ons-u-pt-s{% endif %}{% if group.placeholderText is not defined and group.rows | length > 1 %} ons-u-bt{% endif %}{% if not group.last %} ons-u-mb-xl{% endif %}">
|
|
116
116
|
<a {% if 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>
|
|
117
117
|
</div>
|
|
118
118
|
{% endif %}
|
|
@@ -115,7 +115,6 @@ const EXAMPLE_SUMMARY_GROUPS = {
|
|
|
115
115
|
{
|
|
116
116
|
id: 'group-id-1',
|
|
117
117
|
groupTitle: 'group title',
|
|
118
|
-
headers: ['Header 1', 'Header 2', 'Header 3'],
|
|
119
118
|
...EXAMPLE_SUMMARY_ROWS,
|
|
120
119
|
},
|
|
121
120
|
],
|
|
@@ -136,6 +135,123 @@ const EXAMPLE_SUMMARY_GROUPS_NO_ROWS = {
|
|
|
136
135
|
],
|
|
137
136
|
};
|
|
138
137
|
|
|
138
|
+
const EXAMPLE_SUMMARY_HOUSEHOLD_GROUP = {
|
|
139
|
+
rows: [
|
|
140
|
+
{
|
|
141
|
+
rowItems: [
|
|
142
|
+
{
|
|
143
|
+
rowTitle: 'row item 1',
|
|
144
|
+
valueList: [
|
|
145
|
+
{
|
|
146
|
+
text: 'list item 1',
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
actions: [
|
|
150
|
+
{
|
|
151
|
+
text: 'Change',
|
|
152
|
+
ariaLabel: 'Change list item',
|
|
153
|
+
url: '#0',
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
text: 'Remove',
|
|
157
|
+
ariaLabel: 'Remove list item',
|
|
158
|
+
url: '#0',
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
rowTitle: 'row item 2',
|
|
164
|
+
valueList: [
|
|
165
|
+
{
|
|
166
|
+
text: 'list item 2',
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
actions: [
|
|
170
|
+
{
|
|
171
|
+
text: 'Change',
|
|
172
|
+
ariaLabel: 'Remove list item',
|
|
173
|
+
url: '#0',
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
rowTitle: 'row item 3',
|
|
179
|
+
valueList: [
|
|
180
|
+
{
|
|
181
|
+
text: 'list item 3',
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
actions: [
|
|
185
|
+
{
|
|
186
|
+
text: 'Change',
|
|
187
|
+
ariaLabel: 'Change list item',
|
|
188
|
+
url: '#0',
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
rowItems: [
|
|
196
|
+
{
|
|
197
|
+
rowTitle: 'row item 4',
|
|
198
|
+
valueList: [
|
|
199
|
+
{
|
|
200
|
+
text: 'list item 4',
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
actions: [
|
|
204
|
+
{
|
|
205
|
+
text: 'Change',
|
|
206
|
+
ariaLabel: 'Change answer',
|
|
207
|
+
url: '#0',
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
text: 'Remove',
|
|
211
|
+
ariaLabel: 'Change list item',
|
|
212
|
+
url: '#0',
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
rowTitle: 'row item 5',
|
|
218
|
+
valueList: [
|
|
219
|
+
{
|
|
220
|
+
text: 'list item 5',
|
|
221
|
+
},
|
|
222
|
+
],
|
|
223
|
+
actions: [
|
|
224
|
+
{
|
|
225
|
+
text: 'Change',
|
|
226
|
+
ariaLabel: 'Change list item',
|
|
227
|
+
url: '#0',
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
rowTitle: 'row item 6',
|
|
233
|
+
valueList: [
|
|
234
|
+
{
|
|
235
|
+
text: 'list item 6',
|
|
236
|
+
},
|
|
237
|
+
],
|
|
238
|
+
actions: [
|
|
239
|
+
{
|
|
240
|
+
text: 'Change',
|
|
241
|
+
ariaLabel: 'Change list item',
|
|
242
|
+
url: '#0',
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
},
|
|
246
|
+
],
|
|
247
|
+
},
|
|
248
|
+
],
|
|
249
|
+
summaryLink: {
|
|
250
|
+
text: 'Summary link',
|
|
251
|
+
url: '#0',
|
|
252
|
+
},
|
|
253
|
+
};
|
|
254
|
+
|
|
139
255
|
const EXAMPLE_SUMMARY_BASIC = {
|
|
140
256
|
summaries: [
|
|
141
257
|
{
|
|
@@ -162,6 +278,31 @@ const EXAMPLE_SUMMARY_WITH_NO_ROWS = {
|
|
|
162
278
|
],
|
|
163
279
|
};
|
|
164
280
|
|
|
281
|
+
const EXAMPLE_SUMMARY_MULTIPLE_GROUPS = {
|
|
282
|
+
summaries: [
|
|
283
|
+
{
|
|
284
|
+
summaryTitle: 'summary title',
|
|
285
|
+
groups: [
|
|
286
|
+
{
|
|
287
|
+
id: 'group-id-1',
|
|
288
|
+
groupTitle: 'group title',
|
|
289
|
+
...EXAMPLE_SUMMARY_ROWS,
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
id: 'group-id-2',
|
|
293
|
+
groupTitle: 'group title',
|
|
294
|
+
...EXAMPLE_SUMMARY_HOUSEHOLD_GROUP,
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
id: 'group-id-3',
|
|
298
|
+
groupTitle: 'group title',
|
|
299
|
+
...EXAMPLE_SUMMARY_ROWS,
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
},
|
|
303
|
+
],
|
|
304
|
+
};
|
|
305
|
+
|
|
165
306
|
describe('macro: summary', () => {
|
|
166
307
|
describe('mode: general', () => {
|
|
167
308
|
it('passes jest-axe checks', async () => {
|
|
@@ -200,6 +341,12 @@ describe('macro: summary', () => {
|
|
|
200
341
|
|
|
201
342
|
expect($('.ons-summary__group-title').text()).toBe('group title');
|
|
202
343
|
});
|
|
344
|
+
|
|
345
|
+
it('has larger margin between groups if the top one is a household style summary', () => {
|
|
346
|
+
const $ = cheerio.load(renderComponent('summary', EXAMPLE_SUMMARY_MULTIPLE_GROUPS));
|
|
347
|
+
|
|
348
|
+
expect($('.ons-summary__group:nth-last-of-type(2) .ons-summary__link').hasClass('ons-u-mb-xl')).toBe(true);
|
|
349
|
+
});
|
|
203
350
|
});
|
|
204
351
|
|
|
205
352
|
describe('part: row', () => {
|
|
@@ -178,7 +178,7 @@ $hub-row-spacing: 1.3rem;
|
|
|
178
178
|
&__item-title,
|
|
179
179
|
&__values,
|
|
180
180
|
&__actions {
|
|
181
|
-
flex:
|
|
181
|
+
flex: 4;
|
|
182
182
|
padding-top: $summary-row-spacing;
|
|
183
183
|
vertical-align: top;
|
|
184
184
|
|
|
@@ -192,9 +192,13 @@ $hub-row-spacing: 1.3rem;
|
|
|
192
192
|
justify-content: right;
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
+
&__button {
|
|
196
|
+
align-self: flex-start;
|
|
197
|
+
}
|
|
198
|
+
|
|
195
199
|
&__item-title,
|
|
196
200
|
&__values {
|
|
197
|
-
flex:
|
|
201
|
+
flex: 7.3;
|
|
198
202
|
}
|
|
199
203
|
|
|
200
204
|
&__item-title--2 {
|
|
@@ -356,14 +356,16 @@ describe('macro: table', () => {
|
|
|
356
356
|
|
|
357
357
|
faker.renderComponent('table', params);
|
|
358
358
|
|
|
359
|
-
expect(buttonSpy.occurrences).toEqual([
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
359
|
+
expect(buttonSpy.occurrences).toEqual([
|
|
360
|
+
{
|
|
361
|
+
text: 'Submit form',
|
|
362
|
+
id: 'submit-form-button',
|
|
363
|
+
classes: 'custom-button-class',
|
|
364
|
+
url: 'https://example.com/link',
|
|
365
|
+
value: '42', // `| safe` filter is used in macro which makes a string
|
|
366
|
+
name: 'submit-form-button-name',
|
|
367
|
+
},
|
|
368
|
+
]);
|
|
367
369
|
});
|
|
368
370
|
});
|
|
369
371
|
});
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
{% from "components/modal/_macro.njk" import onsModal %}
|
|
2
2
|
{% macro onsTimeoutModal(params) %}
|
|
3
3
|
{% call onsModal({
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
%}
|
|
4
|
+
"title": params.title,
|
|
5
|
+
"btnText": params.btnText,
|
|
6
|
+
"classes": "ons-js-timeout-modal",
|
|
7
|
+
"enableGA": params.enableGA,
|
|
8
|
+
"attributes": {
|
|
9
|
+
"data-redirect-url": params.redirectUrl,
|
|
10
|
+
"data-server-session-expires-at": params.sessionExpiresAt,
|
|
11
|
+
"data-show-modal-time": params.showModalTimeInSeconds,
|
|
12
|
+
"data-server-session-expiry-endpoint": params.serverSessionExpiryEndpoint,
|
|
13
|
+
"data-countdown-text": params.countdownText,
|
|
14
|
+
"data-countdown-expired-text": params.countdownExpiredText,
|
|
15
|
+
"data-minutes-text-singular": params.minutesTextSingular,
|
|
16
|
+
"data-minutes-text-plural": params.minutesTextPlural,
|
|
17
|
+
"data-seconds-text-singular": params.secondsTextSingular,
|
|
18
|
+
"data-seconds-text-plural": params.secondsTextPlural,
|
|
19
|
+
"data-full-stop": params.endWithFullStop,
|
|
20
|
+
"aria-describedby": "timeout-time-remaining"
|
|
21
|
+
}
|
|
22
|
+
}) %}
|
|
24
23
|
<p>{{ params.textFirstLine }}</p>
|
|
25
24
|
<p class="ons-js-timeout-timer" aria-hidden="true" aria-relevant="additions"></p>
|
|
26
25
|
<p class="ons-js-timeout-timer-acc ons-u-vh" role="status" id="timeout-time-remaining"></p>
|