@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.
Files changed (47) hide show
  1. package/components/access-code/_macro.njk +6 -8
  2. package/components/accordion/_macro.njk +2 -3
  3. package/components/accordion/_macro.spec.js +9 -9
  4. package/components/accordion/accordion.dom.js +4 -4
  5. package/components/accordion/accordion.js +14 -14
  6. package/components/accordion/accordion.spec.js +6 -6
  7. package/components/collapsible/_macro.njk +20 -28
  8. package/components/collapsible/_macro.spec.js +15 -15
  9. package/components/{collapsible/_collapsible.scss → details/_details.scss} +14 -14
  10. package/components/details/_macro.njk +30 -0
  11. package/components/details/_macro.spec.js +151 -0
  12. package/components/details/details.dom.js +13 -0
  13. package/components/details/details.js +66 -0
  14. package/components/details/details.spec.js +103 -0
  15. package/components/hero/_hero.scss +2 -2
  16. package/components/modal/modal.js +12 -6
  17. package/components/modal/modal.spec.js +0 -11
  18. package/components/question/_macro.njk +4 -4
  19. package/components/question/_macro.spec.js +14 -14
  20. package/components/summary/_macro.njk +1 -1
  21. package/components/summary/_macro.spec.js +148 -1
  22. package/components/summary/_summary.scss +6 -2
  23. package/components/table/_macro.spec.js +10 -8
  24. package/components/timeout-modal/_macro.njk +19 -20
  25. package/components/timeout-modal/timeout-modal.spec.js +17 -13
  26. package/components/video/_macro.njk +18 -4
  27. package/components/video/_macro.spec.js +46 -33
  28. package/components/video/_video.scss +4 -0
  29. package/components/video/video.dom.js +13 -0
  30. package/components/video/video.js +30 -0
  31. package/components/video/video.spec.js +72 -0
  32. package/css/main.css +3 -3
  33. package/css/print.css +1 -1
  34. package/js/analytics.js +1 -5
  35. package/js/main.js +2 -1
  36. package/js/timeout.js +7 -0
  37. package/package.json +2 -1
  38. package/scripts/main.es5.js +1 -1
  39. package/scripts/main.js +1 -1
  40. package/scss/main.scss +1 -1
  41. package/scss/objects/_page.scss +1 -1
  42. package/scss/objects/_spacing.scss +1 -1
  43. package/scss/overrides/hcm.scss +1 -1
  44. package/scss/print.scss +1 -1
  45. package/components/collapsible/collapsible.dom.js +0 -13
  46. package/components/collapsible/collapsible.js +0 -66
  47. 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-collapsible {
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-collapsible__heading {
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.setGaAttributes = component.getAttribute('data-enable-ga');
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
- this.component.setAttribute('data-ga-action', `Modal initialised`);
37
- this.component.setAttribute('data-ga-label', `${this.modalType} modal initialised`);
38
- this.component.setAttribute('data-ga-category', `${this.modalType} modal`);
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.setGaAttributes) {
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.setGaAttributes) {
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/collapsible/_macro.njk" import onsCollapsible %}
22
- {% call onsCollapsible({
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/collapsible/_macro.njk" import onsCollapsible %}
113
- {% call onsCollapsible({
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 collapsible', () => {
166
+ it('outputs the expected details', () => {
167
167
  const faker = templateFaker();
168
- const collapsibleSpy = faker.spy('collapsible');
168
+ const detailsSpy = faker.spy('details');
169
169
 
170
170
  faker.renderComponent('question', EXAMPLE_QUESTION_DEFINITION);
171
171
 
172
- expect(collapsibleSpy.occurrences[0]).toHaveProperty('classes', 'ons-u-mb-m');
173
- expect(collapsibleSpy.occurrences[0]).toHaveProperty('id', 'definition-id');
174
- expect(collapsibleSpy.occurrences[0]).toHaveProperty('title', 'Definition title');
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 collapsible call content', () => {
177
+ it('outputs the expected details call content', () => {
178
178
  const $ = cheerio.load(renderComponent('question', EXAMPLE_QUESTION_DEFINITION));
179
179
 
180
- expect($('.ons-collapsible__content > p').text()).toBe('Definition content');
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 collapsible', () => {
230
+ it('outputs the expected details', () => {
231
231
  const faker = templateFaker();
232
- const collapsibleSpy = faker.spy('collapsible');
232
+ const detailsSpy = faker.spy('details');
233
233
 
234
234
  faker.renderComponent('question', EXAMPLE_QUESTION_JUSTIFICATION);
235
235
 
236
- expect(collapsibleSpy.occurrences[0]).toHaveProperty('classes', 'ons-u-mb-m');
237
- expect(collapsibleSpy.occurrences[0]).toHaveProperty('id', 'justification-id');
238
- expect(collapsibleSpy.occurrences[0]).toHaveProperty('title', 'Justification title');
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 collapsible call content', () => {
241
+ it('outputs the expected details call content', () => {
242
242
  const $ = cheerio.load(renderComponent('question', EXAMPLE_QUESTION_JUSTIFICATION));
243
243
 
244
- expect($('.ons-collapsible__content > p').text()).toBe('Justification content');
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: 2;
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: 6.19;
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
- text: 'Submit form',
361
- id: 'submit-form-button',
362
- classes: 'custom-button-class',
363
- url: 'https://example.com/link',
364
- value: '42', // `| safe` filter is used in macro which makes a string
365
- name: 'submit-form-button-name',
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
- "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
- })
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>