@ons/design-system 64.0.0 → 65.1.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.
Files changed (124) hide show
  1. package/components/access-code/_macro.njk +2 -2
  2. package/components/access-code/_macro.spec.js +2 -2
  3. package/components/access-code/access-code.dom.js +11 -0
  4. package/components/access-code/{uac.js → access-code.js} +1 -1
  5. package/components/access-code/{uac.scss → access-code.scss} +1 -1
  6. package/components/access-code/example-access-code-error.njk +6 -6
  7. package/components/access-code/example-access-code.njk +4 -4
  8. package/components/accordion/_macro.njk +2 -2
  9. package/components/accordion/_macro.spec.js +3 -3
  10. package/components/accordion/accordion.dom.js +1 -1
  11. package/components/accordion/accordion.js +1 -1
  12. package/components/address-input/autosuggest.address.error.js +1 -1
  13. package/components/address-input/autosuggest.address.js +2 -2
  14. package/components/address-input/autosuggest.address.spec.js +5 -5
  15. package/components/autosuggest/_autosuggest.scss +11 -6
  16. package/components/autosuggest/_macro.njk +32 -31
  17. package/components/autosuggest/_macro.spec.js +18 -18
  18. package/components/autosuggest/autosuggest.spec.js +31 -31
  19. package/components/autosuggest/autosuggest.ui.js +8 -9
  20. package/components/breadcrumbs/_breadcrumbs.scss +6 -6
  21. package/components/breadcrumbs/_macro.njk +4 -4
  22. package/components/breadcrumbs/_macro.spec.js +13 -13
  23. package/components/button/_button.scss +27 -27
  24. package/components/button/_macro.spec.js +2 -2
  25. package/components/call-to-action/_macro.njk +1 -1
  26. package/components/card/_card.scss +14 -0
  27. package/components/card/_macro.njk +7 -8
  28. package/components/checkboxes/example-checkboxes-with-revealed-checkboxes-expanded.njk +88 -0
  29. package/components/checkboxes/example-checkboxes-with-revealed-radios-expanded.njk +70 -0
  30. package/components/checkboxes/example-checkboxes-with-revealed-select-expanded.njk +72 -0
  31. package/components/checkboxes/example-checkboxes-with-revealed-text-input-expanded.njk +60 -0
  32. package/components/content-pagination/_content-pagination.scss +1 -1
  33. package/components/date-input/_macro.njk +3 -3
  34. package/components/date-input/_macro.spec.js +118 -0
  35. package/components/date-input/example-date-input-error-for-single-field.njk +63 -0
  36. package/components/details/_details.scss +1 -1
  37. package/components/document-list/_macro.njk +5 -7
  38. package/components/document-list/_macro.spec.js +2 -2
  39. package/components/document-list/example-document-list-search-result-featured.njk +1 -1
  40. package/components/document-list/example-document-list-search-results.njk +3 -3
  41. package/components/external-link/_external-link.scss +3 -3
  42. package/components/external-link/_macro.njk +1 -1
  43. package/components/fieldset/_fieldset.scss +1 -1
  44. package/components/footer/_footer.scss +2 -2
  45. package/components/footer/example-footer-with-alternative-organisation.njk +5 -5
  46. package/components/header/_header.scss +8 -8
  47. package/components/header/_macro.njk +4 -4
  48. package/components/header/example-header-external-with-navigation.njk +5 -5
  49. package/components/header/example-header-external-with-service-links.njk +3 -3
  50. package/components/header/example-header-external-with-sub-navigation.njk +10 -10
  51. package/components/header/example-header-internal.njk +2 -2
  52. package/components/header/example-header-neutral-for-multicoloured-logo.njk +6 -6
  53. package/components/icon/_icon.scss +1 -1
  54. package/components/icon/_macro.njk +35 -35
  55. package/components/icon/_macro.spec.js +1 -1
  56. package/components/image/_image.scss +2 -2
  57. package/components/image/_macro.njk +4 -6
  58. package/components/image/_macro.spec.js +10 -10
  59. package/components/list/_list.scss +5 -2
  60. package/components/list/_macro.njk +22 -10
  61. package/components/list/_macro.spec.js +42 -0
  62. package/components/mutually-exclusive/_macro.njk +4 -3
  63. package/components/navigation/_macro.njk +6 -6
  64. package/components/navigation/_macro.spec.js +4 -4
  65. package/components/pagination/_macro.njk +17 -2
  66. package/components/pagination/_pagination.scss +14 -0
  67. package/components/pagination/example-pagination-first.njk +0 -2
  68. package/components/pagination/example-pagination-last.njk +0 -2
  69. package/components/pagination/example-pagination-with-no-range-indicator.njk +0 -2
  70. package/components/pagination/example-pagination.njk +0 -2
  71. package/components/panel/_macro.njk +1 -1
  72. package/components/panel/_panel.scss +7 -7
  73. package/components/password/_macro.njk +1 -1
  74. package/components/password/example-password.njk +1 -2
  75. package/components/question/example-question-interviewer-note.njk +1 -1
  76. package/components/quote/_quote.scss +1 -1
  77. package/components/radios/_macro.njk +1 -1
  78. package/components/radios/example-radios-with-clear-button-expanded.njk +98 -0
  79. package/components/radios/example-radios-with-revealed-checkboxes-expanded.njk +70 -0
  80. package/components/radios/example-radios-with-revealed-radios-expanded.njk +69 -0
  81. package/components/radios/example-radios-with-revealed-select-expanded.njk +70 -0
  82. package/components/radios/example-radios-with-revealed-text-input-expanded.njk +81 -0
  83. package/components/relationships/_macro.spec.js +9 -11
  84. package/components/relationships/example-relationships-error.njk +28 -28
  85. package/components/relationships/example-relationships-you.njk +29 -29
  86. package/components/relationships/example-relationships.njk +28 -28
  87. package/components/relationships/relationships.spec.js +13 -13
  88. package/components/reply/_macro.njk +5 -2
  89. package/components/reply/_macro.spec.js +7 -1
  90. package/components/section-navigation/_macro.njk +2 -1
  91. package/components/section-navigation/_macro.spec.js +2 -13
  92. package/components/skip-to-content/_macro.njk +2 -1
  93. package/components/skip-to-content/_macro.spec.js +17 -3
  94. package/components/skip-to-content/_skip.scss +1 -1
  95. package/components/skip-to-content/skip-to-content.dom.js +1 -1
  96. package/components/skip-to-content/skip-to-content.spec.js +3 -3
  97. package/components/summary/_summary.scss +1 -1
  98. package/components/table/_table.scss +6 -6
  99. package/components/table/sortable-table.js +1 -1
  100. package/components/tabs/_macro.njk +5 -5
  101. package/components/tabs/_macro.spec.js +1 -1
  102. package/components/tabs/example-tabs-details.njk +3 -0
  103. package/components/tabs/example-tabs.njk +0 -1
  104. package/components/textarea/example-textarea-error.njk +4 -4
  105. package/components/timeline/_macro.njk +18 -22
  106. package/components/timeline/_macro.spec.js +18 -0
  107. package/components/video/example-video.njk +1 -1
  108. package/components/video/video.js +10 -1
  109. package/components/video/video.spec.js +33 -0
  110. package/css/main.css +3 -3
  111. package/css/print.css +1 -1
  112. package/js/cookies-settings.js +1 -1
  113. package/js/main.js +1 -1
  114. package/package.json +19 -21
  115. package/scripts/main.es5.js +1 -1
  116. package/scripts/main.js +1 -1
  117. package/scss/base/_global.scss +1 -1
  118. package/scss/main.scss +1 -1
  119. package/scss/objects/_spacing.scss +3 -3
  120. package/scss/overrides/hcm.scss +10 -10
  121. package/scss/overrides/rtl.scss +2 -2
  122. package/scss/print.scss +2 -2
  123. package/components/access-code/uac.dom.js +0 -11
  124. /package/components/access-code/{uac.spec.js → access-code.spec.js} +0 -0
@@ -2,7 +2,7 @@ import { renderComponent, setTestPage } from '../../tests/helpers/rendering';
2
2
 
3
3
  const EXAMPLE_RELATIONSHIPS = {
4
4
  dontWrap: true,
5
- playback: "Amanda Bloggs is Joe Bloggs' <em>…</em>",
5
+ playback: "Amanda Bloggs is Joe Bloggs' <strong>…</strong>",
6
6
  name: 'relationship',
7
7
  radios: [
8
8
  {
@@ -12,8 +12,8 @@ const EXAMPLE_RELATIONSHIPS = {
12
12
  text: 'Grandparent',
13
13
  },
14
14
  attributes: {
15
- 'data-title': 'Thinking of Joe Bloggs, Amanda Bloggs is their <em>grandparents</em>',
16
- 'data-playback': "Amanda Bloggs is Joe Bloggs' <em>grandparents</em>",
15
+ 'data-title': 'Thinking of Joe Bloggs, Amanda Bloggs is their <strong>grandparents</strong>',
16
+ 'data-playback': "Amanda Bloggs is Joe Bloggs' <strong>grandparents</strong>",
17
17
  },
18
18
  },
19
19
  {
@@ -23,8 +23,8 @@ const EXAMPLE_RELATIONSHIPS = {
23
23
  text: 'Other relation',
24
24
  },
25
25
  attributes: {
26
- 'data-title': 'Thinking of Joe Bloggs, Amanda Bloggs is their <em>other relation</em>',
27
- 'data-playback': "Amanda Bloggs is Joe Bloggs' <em>other relation</em>",
26
+ 'data-title': 'Thinking of Joe Bloggs, Amanda Bloggs is their <strong>other relation</strong>',
27
+ 'data-playback': "Amanda Bloggs is Joe Bloggs' <strong>other relation</strong>",
28
28
  },
29
29
  },
30
30
  {
@@ -35,8 +35,8 @@ const EXAMPLE_RELATIONSHIPS = {
35
35
  description: 'Including foster child',
36
36
  },
37
37
  attributes: {
38
- 'data-title': 'Thinking of Joe Bloggs, Amanda Bloggs is <em>unrelated</em> to Joe Bloggs',
39
- 'data-playback': 'Amanda Bloggs is <em>unrelated</em> to Joe Bloggs',
38
+ 'data-title': 'Thinking of Joe Bloggs, Amanda Bloggs is <strong>unrelated</strong> to Joe Bloggs',
39
+ 'data-playback': 'Amanda Bloggs is <strong>unrelated</strong> to Joe Bloggs',
40
40
  },
41
41
  },
42
42
  ],
@@ -49,7 +49,7 @@ describe('script: relationships', () => {
49
49
  renderComponent(
50
50
  'question',
51
51
  {
52
- title: 'Thinking of Joe Bloggs, Amanda Bloggs is their <em>…</em>',
52
+ title: 'Thinking of Joe Bloggs, Amanda Bloggs is their <strong>…</strong>',
53
53
  readDescriptionFirst: true,
54
54
  legendIsQuestionTitle: true,
55
55
  legendTitleClasses: 'ons-js-relationships-legend',
@@ -61,7 +61,7 @@ describe('script: relationships', () => {
61
61
 
62
62
  describe('when the component initialises', () => {
63
63
  it('then the playback paragraph should become visible', async () => {
64
- const hasHideClass = await page.$eval('.ons-relationships__playback', node => node.classList.contains('ons-u-d-no'));
64
+ const hasHideClass = await page.$eval('.ons-relationships__playback', (node) => node.classList.contains('ons-u-d-no'));
65
65
  expect(hasHideClass).toBe(false);
66
66
  });
67
67
  });
@@ -72,13 +72,13 @@ describe('script: relationships', () => {
72
72
  });
73
73
 
74
74
  it('the question title should be changed to reflect the relationship', async () => {
75
- const headingText = await page.$eval('h1', element => element.innerHTML);
76
- expect(headingText.trim()).toBe('Thinking of Joe Bloggs, Amanda Bloggs is their <em>other relation</em>');
75
+ const headingText = await page.$eval('h1', (element) => element.innerHTML);
76
+ expect(headingText.trim()).toBe('Thinking of Joe Bloggs, Amanda Bloggs is their <strong>other relation</strong>');
77
77
  });
78
78
 
79
79
  it('the playback should be changed to reflect the relationship', async () => {
80
- const playbackText = await page.$eval('.ons-relationships__playback', element => element.innerHTML);
81
- expect(playbackText.trim()).toBe("Amanda Bloggs is Joe Bloggs' <em>other relation</em>");
80
+ const playbackText = await page.$eval('.ons-relationships__playback', (element) => element.innerHTML);
81
+ expect(playbackText.trim()).toBe("Amanda Bloggs is Joe Bloggs' <strong>other relation</strong>");
82
82
  });
83
83
  });
84
84
  });
@@ -7,8 +7,11 @@
7
7
  "id": params.textarea.id,
8
8
  "name": params.textarea.name,
9
9
  "label": {
10
- "text": params.textarea.label.text
11
- }
10
+ "text": params.textarea.label.text,
11
+ "description": params.textarea.label.description
12
+ },
13
+ "charCheckLimit": params.textarea.charCheckLimit,
14
+ "rows": params.textarea.rows
12
15
  })
13
16
  }}
14
17
  <div class="ons-grid ons-grid--flex ons-grid--gutterless ons-grid--vertical-center ons-grid--no-wrap@s ons-u-mt-m ons-u-mb-m">
@@ -10,7 +10,14 @@ const EXAMPLE_TEXTAREA = {
10
10
  name: 'reply',
11
11
  label: {
12
12
  text: 'Reply',
13
+ description: 'Reply description',
13
14
  },
15
+ charCheckLimit: {
16
+ limit: 300,
17
+ charCountSingular: '{x} more character needed',
18
+ charCountPlural: '{x} more characters needed',
19
+ },
20
+ rows: 5,
14
21
  };
15
22
 
16
23
  const EXAMPLE_BUTTON = {
@@ -40,7 +47,6 @@ describe('macro: reply', () => {
40
47
  const textareaSpy = faker.spy('textarea');
41
48
 
42
49
  cheerio.load(faker.renderComponent('reply', EXAMPLE_REPLY));
43
-
44
50
  expect(textareaSpy.occurrences[0]).toEqual(EXAMPLE_TEXTAREA);
45
51
  });
46
52
 
@@ -1,5 +1,6 @@
1
1
  {% macro onsSectionNavigation(params) %}
2
- <nav class="ons-section-nav{% if params.variants == 'vertical' %} ons-section-nav--vertical{% endif %} {% if params.classes %} {{ params.classes }} {% endif %}"{% if params.id %} id="{{ params.id }}"{% endif %} aria-label="{{ params.ariaLabel | default("Section menu") }}">
2
+ <nav class="ons-section-nav{% if params.variants == 'vertical' %} ons-section-nav--vertical{% endif %} {% if params.classes %} {{ params.classes }} {% endif %}"{% if params.id %} id="{{ params.id }}"{% endif %} aria-labelledby="{{ params.hiddenTitleId | default("section-menu-nav-title")}}">
3
+ <h2 class="ons-u-vh" id="{{ params.hiddenTitleId | default("section-menu-nav-title") }}">{{ params.hiddenTitle | default("Pages in this section") }}</h2>
3
4
  {% if params.sections %}
4
5
  {% for section in params.sections %}
5
6
  <div class="ons-section-nav__sub">
@@ -135,21 +135,10 @@ describe('macro: section-navigation', () => {
135
135
  expect($('.ons-section-nav').hasClass('custom-class')).toBe(true);
136
136
  });
137
137
 
138
- it('has the provided `ariaLabel` parameter', () => {
139
- const $ = cheerio.load(
140
- renderComponent('section-navigation', {
141
- ...EXAMPLE_SECTION_NAVIGATION,
142
- ariaLabel: 'Section navigation menu',
143
- }),
144
- );
145
-
146
- expect($('.ons-section-nav').attr('aria-label')).toBe('Section navigation menu');
147
- });
148
-
149
- it('assumes a default `ariaLabel` of "Section menu"', () => {
138
+ it('assumes a default `hiddenTitleId` of "Section menu"', () => {
150
139
  const $ = cheerio.load(renderComponent('section-navigation', EXAMPLE_SECTION_NAVIGATION));
151
140
 
152
- expect($('.ons-section-nav').attr('aria-label')).toBe('Section menu');
141
+ expect($('.ons-section-nav').attr('aria-labelledby')).toBe('section-menu-nav-title');
153
142
  });
154
143
 
155
144
  describe('navigation items', () => {
@@ -1,3 +1,4 @@
1
1
  {% macro onsSkipToContent(params) %}
2
- <a class="ons-skip-link" href="{{ params.url }}">{{ params.text }}</a>
2
+ {% set text = params.text | default('Skip to content') %}
3
+ <a class="ons-skip-to-content" href="{{ params.url }}">{{ text }}</a>
3
4
  {% endmacro %}
@@ -26,7 +26,7 @@ describe('macro: skip-to-content', () => {
26
26
  }),
27
27
  );
28
28
 
29
- expect($('.ons-skip-link')[0].tagName).toBe('a');
29
+ expect($('.ons-skip-to-content')[0].tagName).toBe('a');
30
30
  });
31
31
 
32
32
  it('has skip link with the provided `url`', async () => {
@@ -37,7 +37,7 @@ describe('macro: skip-to-content', () => {
37
37
  }),
38
38
  );
39
39
 
40
- expect($('.ons-skip-link').attr('href')).toBe('#example-anchor');
40
+ expect($('.ons-skip-to-content').attr('href')).toBe('#example-anchor');
41
41
  });
42
42
 
43
43
  it('has skip link with the provided `text`', async () => {
@@ -49,9 +49,23 @@ describe('macro: skip-to-content', () => {
49
49
  );
50
50
 
51
51
  expect(
52
- $('.ons-skip-link')
52
+ $('.ons-skip-to-content')
53
53
  .text()
54
54
  .trim(),
55
55
  ).toBe('Skip to the content');
56
56
  });
57
+
58
+ it('has skip link with the default text if no text provided`', async () => {
59
+ const $ = cheerio.load(
60
+ renderComponent('skip-to-content', {
61
+ url: '#example-anchor',
62
+ }),
63
+ );
64
+
65
+ expect(
66
+ $('.ons-skip-to-content')
67
+ .text()
68
+ .trim(),
69
+ ).toBe('Skip to content');
70
+ });
57
71
  });
@@ -1,4 +1,4 @@
1
- .ons-skip-link {
1
+ .ons-skip-to-content {
2
2
  clip: rect(0 0 0 0);
3
3
  clip-path: inset(50%);
4
4
  display: block;
@@ -2,7 +2,7 @@ import domready from '../../js/domready';
2
2
  import skipToMain from './skip-to-content';
3
3
 
4
4
  async function initaliseSkipToLink() {
5
- const links = [...document.querySelectorAll('.ons-skip-link')];
5
+ const links = [...document.querySelectorAll('.ons-skip-to-content')];
6
6
  if (links.length) {
7
7
  links.forEach(link => {
8
8
  skipToMain(link);
@@ -15,7 +15,7 @@ describe('script: skip-to-content', () => {
15
15
  it('sets `tabIndex` of target element to -1', async () => {
16
16
  await setTestPage('/test', EXAMPLE_SKIP_TO_LINK_TEMPLATE);
17
17
 
18
- await page.focus('.ons-skip-link');
18
+ await page.focus('.ons-skip-to-content');
19
19
  await page.keyboard.press('Enter');
20
20
 
21
21
  const targetTabIndex = await page.$eval('#target-element', el => el.tabIndex);
@@ -25,7 +25,7 @@ describe('script: skip-to-content', () => {
25
25
  it('removes outline from target element on navigate', async () => {
26
26
  await setTestPage('/test', EXAMPLE_SKIP_TO_LINK_TEMPLATE);
27
27
 
28
- await page.focus('.ons-skip-link');
28
+ await page.focus('.ons-skip-to-content');
29
29
  await page.keyboard.press('Enter');
30
30
 
31
31
  const targetOutline = await page.$eval('#target-element', el => el.style.outline);
@@ -35,7 +35,7 @@ describe('script: skip-to-content', () => {
35
35
  it('focuses target element on navigate', async () => {
36
36
  await setTestPage('/test', EXAMPLE_SKIP_TO_LINK_TEMPLATE);
37
37
 
38
- await page.focus('.ons-skip-link');
38
+ await page.focus('.ons-skip-to-content');
39
39
  await page.keyboard.press('Enter');
40
40
 
41
41
  const focusedElementId = await page.evaluate(() => document.activeElement.id);
@@ -80,7 +80,7 @@ $hub-row-spacing: 1.3rem;
80
80
  left: 0;
81
81
  position: absolute;
82
82
  text-align: center;
83
- &--check .ons-svg-icon {
83
+ &--check .ons-icon {
84
84
  fill: var(--ons-color-leaf-green) !important;
85
85
  }
86
86
  }
@@ -155,7 +155,7 @@
155
155
 
156
156
  &--sortable {
157
157
  [aria-sort='descending'].ons-table__header {
158
- .ons-svg-icon {
158
+ .ons-icon {
159
159
  .ons-topTriangle {
160
160
  fill: var(--ons-color-grey-15);
161
161
  }
@@ -164,7 +164,7 @@
164
164
  }
165
165
  }
166
166
  .ons-table__sort-button:focus {
167
- .ons-svg-icon {
167
+ .ons-icon {
168
168
  .ons-topTriangle {
169
169
  fill: #e3ba02;
170
170
  }
@@ -173,7 +173,7 @@
173
173
  }
174
174
 
175
175
  [aria-sort='ascending'].ons-table__header {
176
- .ons-svg-icon {
176
+ .ons-icon {
177
177
  .ons-topTriangle {
178
178
  fill: var(--ons-color-text);
179
179
  }
@@ -182,7 +182,7 @@
182
182
  }
183
183
  }
184
184
  .ons-table__sort-button:focus {
185
- .ons-svg-icon {
185
+ .ons-icon {
186
186
  .ons-bottomTriangle {
187
187
  fill: #e3ba02;
188
188
  }
@@ -210,7 +210,7 @@
210
210
  text-underline-position: under;
211
211
  }
212
212
 
213
- .ons-svg-icon {
213
+ .ons-icon {
214
214
  fill: var(--ons-color-grey-75);
215
215
  height: 16px;
216
216
  margin-left: 0.2rem;
@@ -220,7 +220,7 @@
220
220
 
221
221
  &:focus {
222
222
  @extend %a-focus;
223
- .ons-svg-icon {
223
+ .ons-icon {
224
224
  fill: var(--ons-color-black);
225
225
  }
226
226
  }
@@ -29,7 +29,7 @@ export default class TableSort {
29
29
  createHeadingButtons(heading, i) {
30
30
  const text = heading.textContent.trim();
31
31
  heading.querySelector('.ons-table__header-text').remove();
32
- heading.querySelector('.ons-svg-icon').classList.remove('ons-u-d-no');
32
+ heading.querySelector('.ons-icon').classList.remove('ons-u-d-no');
33
33
  const button = document.createElement('button');
34
34
  button.setAttribute('aria-label', this.table.getAttribute('data-aria-sort') + ' ' + text);
35
35
  button.setAttribute('type', 'button');
@@ -13,11 +13,11 @@
13
13
  {% set titleTag = params.titleTag | default("h2") %}
14
14
  <{{ titleTag }} class="ons-tabs__title ons-u-fs-r--b ons-u-mt-no">{{ params.title }}</{{ titleTag }}>
15
15
  <div>
16
- <ul class="ons-tabs__list">
17
- {%- for tab in params.tabs -%}
18
- <li class="ons-tab__list-item"><a href="#{{ tab.id if tab.id else tab.title|trim|replace(' ','-')|lower}}" class="ons-tab" data-ga="click" data-ga-category="tabs" data-ga-action="Show: {{ tab.title }}" data-ga-label="Show: {{ tab.title }}">{{ tab.title }}{% if tab.hiddenSpan %}<span class='ons-u-d-no'>{{tab.hiddenSpan}}</span>{% endif %}</a></li>
19
- {%- endfor -%}
20
- </ul>
16
+ <ul class="ons-tabs__list">
17
+ {%- for tab in params.tabs -%}
18
+ <li class="ons-tab__list-item"><a href="#{{ tab.id if tab.id else tab.title|trim|replace(' ','-')|lower}}" class="ons-tab" data-ga="click" data-ga-category="tabs" data-ga-action="Show: {{ tab.title }}" data-ga-label="Show: {{ tab.title }}">{{ tab.title }}{% if tab.hiddenSpan %}<span class='ons-u-vh'>{{tab.hiddenSpan}}</span>{% endif %}</a></li>
19
+ {%- endfor -%}
20
+ </ul>
21
21
  </div>
22
22
  {% for tab in params.tabs %}
23
23
  <section id="{{ tab.id if tab.id else tab.title|trim|replace(' ','-')|lower }}" class="ons-tabs__panel">
@@ -112,7 +112,7 @@ describe('macro: tabs', () => {
112
112
  it('has expected label text in tab links and visually hidden span in tab 1', () => {
113
113
  const $ = cheerio.load(renderComponent('tabs', EXAMPLE_TABS));
114
114
 
115
- expect($('.ons-tab:first').html()).toBe('Tab 1<span class="ons-u-d-no">for Example</span>');
115
+ expect($('.ons-tab:first').html()).toBe('Tab 1<span class="ons-u-vh">for Example</span>');
116
116
  expect(
117
117
  $('.ons-tab:last')
118
118
  .text()
@@ -30,6 +30,7 @@
30
30
  {
31
31
  "id": "video-description",
32
32
  "title": 'Description',
33
+ "hiddenSpan": 'for Census 2021 promotional TV advert video',
33
34
  "content": '<div class="example-video-block__details">
34
35
  <h3 class="ons-u-d-no@s">Description</h3>
35
36
  <p>The census provides a snapshot of everyone in England & Wales. We help local councils get the funding they need.</p>
@@ -39,6 +40,7 @@
39
40
  {
40
41
  "id": "video-transcript",
41
42
  "title": 'Transcript',
43
+ "hiddenSpan": 'for Census 2021 promotional TV advert video',
42
44
  "content": '<div class="example-video-block__details">
43
45
  <h3 class="ons-u-d-no@s">Transcript</h3>
44
46
  <p>I count.</p>
@@ -50,6 +52,7 @@
50
52
  {
51
53
  "id": "video-embed",
52
54
  "title": 'Embed',
55
+ "hiddenSpan": 'code for Census 2021 promotional TV advert video',
53
56
  "content": '<h3 class="ons-u-d-no@s">Embed</h3>
54
57
  <pre class="language-html"><code>' ~ '<iframe width="560" height="315" src="https://www.youtube.com/embed/_EGJlvkgbPo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>' | e ~ '</code></pre>'
55
58
  }
@@ -8,7 +8,6 @@
8
8
  "id": "ukis",
9
9
  "title": 'UKIS',
10
10
  "showTitle": true,
11
- "hiddenSpan": 'for UKIS',
12
11
  "content": '<h3>Aim of this survey</h3>
13
12
  <p class="ons-u-fs-r">The aim of the UK Innovation Survey (UKIS) is to collect data from businesses about various aspects of their innovation related activities. Using this data we can measure the level, types and trends in innovation.</p>
14
13
  <h3>How we’ll use this data</h3>
@@ -8,9 +8,9 @@
8
8
  "text": "Please provide some feedback",
9
9
  "description": "For example, describe any difficulties you experienced in the use of this service"
10
10
  },
11
- "error": {
12
- "id": "feedback-error",
13
- "text": "Enter your feedback"
14
- }
11
+ "error": {
12
+ "id": "feedback-error",
13
+ "text": "Enter your feedback"
14
+ }
15
15
  })
16
16
  }}
@@ -3,30 +3,26 @@
3
3
  {% from "components/list/_macro.njk" import onsList %}
4
4
 
5
5
  <div class="ons-timeline{{ ' ' + params.classes if params.classes else '' }}">
6
-
6
+ {% set titleTag = params.titleTag | default("h2") %}
7
7
  {% for item in params.items %}
8
- <div class="ons-timeline__item">
9
-
10
- <h2 class="ons-timeline__heading">{{ item.heading }}</h2>
11
-
12
- {% if item.itemsList %}
13
-
14
- {{
15
- onsList({
16
- "variants": 'bare',
17
- "itemsList": item.itemsList
18
- })
19
- }}
20
-
21
- {% else %}
22
-
23
- {{ item.content | safe }}
24
-
25
- {% endif %}
26
-
27
- </div>
8
+ <div class="ons-timeline__item">
9
+ <{{ titleTag }} class="ons-timeline__heading">{{ item.heading }}</{{ titleTag }}>
10
+ {% if item.itemsList %}
11
+ <div class="ons-timeline__content">
12
+ {{
13
+ onsList({
14
+ "variants": 'bare',
15
+ "itemsList": item.itemsList
16
+ })
17
+ }}
18
+ </div>
19
+ {% elif item.content %}
20
+ <div class="ons-timeline__content">
21
+ {{ item.content | safe }}
22
+ </div>
23
+ {% endif %}
24
+ </div>
28
25
  {% endfor %}
29
-
30
26
  </div>
31
27
 
32
28
  {% endmacro %}
@@ -63,6 +63,24 @@ describe('macro: timeline', () => {
63
63
  expect($secondItem.text()).toContain('Timeline entry 2');
64
64
  });
65
65
 
66
+ it('renders a heading based upon titleTag parameter', () => {
67
+ const EXAMPLE_TIMELINE_WITH_TITLE_TAG = {
68
+ ...EXAMPLE_TIMELINE,
69
+ titleTag: 'h3',
70
+ };
71
+ const $ = cheerio.load(renderComponent('timeline', EXAMPLE_TIMELINE_WITH_TITLE_TAG));
72
+ const $firstItem = $('.ons-timeline__item:nth-child(1)');
73
+ expect($firstItem.html().includes('h3')).toBe(true);
74
+ });
75
+
76
+ it('has a provided ons-timeline__content class, wrapping the content', () => {
77
+ const $ = cheerio.load(renderComponent('timeline', EXAMPLE_TIMELINE));
78
+
79
+ const $content = $('.ons-timeline__content');
80
+
81
+ expect($content.length).toBe(3);
82
+ });
83
+
66
84
  it('has the provided inner item list', () => {
67
85
  const faker = templateFaker();
68
86
  const listSpy = faker.spy('list');
@@ -11,4 +11,4 @@
11
11
  "title": 'Census 2021 promotional TV advert',
12
12
  "linkText": 'Watch “Census 2021 promotional TV advert“ on Youtube'
13
13
  })
14
- }}
14
+ }}
@@ -22,10 +22,19 @@ export default class Video {
22
22
  }
23
23
 
24
24
  showIframe() {
25
- const src = this.iframe.getAttribute('data-src');
25
+ const src = this.addDNTtoVimeoVideos();
26
26
  this.iframe.src = src;
27
27
  this.iframe.classList.remove('ons-u-d-no');
28
28
  this.component.classList.add('ons-video--hasIframe');
29
29
  this.placeholder.classList.add('ons-u-d-no');
30
30
  }
31
+ addDNTtoVimeoVideos() {
32
+ let src = this.iframe.getAttribute('data-src');
33
+ if (src.includes('player.vimeo.com/video') && src.includes('?dnt=1') === false) {
34
+ src += '?dnt=1';
35
+ return src;
36
+ } else {
37
+ return src;
38
+ }
39
+ }
31
40
  }
@@ -5,6 +5,11 @@ const EXAMPLE_VIDEO_YOUTUBE = {
5
5
  title: 'Census 2021 promotional TV advert',
6
6
  linkText: 'Example link text',
7
7
  };
8
+ const EXAMPLE_VIDEO_VIMEO = {
9
+ videoEmbedUrl: 'https://player.vimeo.com/video/838454524?h=24551a3754',
10
+ title: 'Vimeo Video',
11
+ linkText: 'Example link text',
12
+ };
8
13
 
9
14
  const EXAMPLE_APPROVED_COOKIE = JSON.stringify({ campaigns: true }).replace(/"/g, "'");
10
15
 
@@ -52,6 +57,18 @@ describe('script: video', () => {
52
57
  const hasClass = await page.$eval('.ons-js-video', node => node.classList.contains('ons-video--hasIframe'));
53
58
  expect(hasClass).toBe(true);
54
59
  }, 10000);
60
+
61
+ it('should not add dnt to YouTube videos', async () => {
62
+ const src = await page.$eval('.ons-js-video-iframe', node => node.getAttribute('src'));
63
+ expect(src.includes('?dnt=1')).toBe(false);
64
+ }, 10000);
65
+
66
+ it('should add dnt to Vimeo videos', async () => {
67
+ await setTestPage('/test', renderComponent('video', EXAMPLE_VIDEO_VIMEO));
68
+
69
+ const src = await page.$eval('.ons-js-video-iframe', node => node.getAttribute('src'));
70
+ expect(src.includes('?dnt=1')).toBe(true);
71
+ }, 10000);
55
72
  });
56
73
 
57
74
  describe('when cookies are accepted via banner', () => {
@@ -78,5 +95,21 @@ describe('script: video', () => {
78
95
  const hasClass = await page.$eval('.ons-js-video', node => node.classList.contains('ons-video--hasIframe'));
79
96
  expect(hasClass).toBe(true);
80
97
  }, 10000);
98
+ it('should not add dnt to YouTube videos', async () => {
99
+ const src = await page.$eval('.ons-js-video-iframe', node => node.getAttribute('src'));
100
+ expect(src.includes('?dnt=1')).toBe(false);
101
+ }, 10000);
102
+
103
+ it('should add dnt to Vimeo videos', async () => {
104
+ await setTestPage(
105
+ '/test',
106
+ `${renderComponent('video', EXAMPLE_VIDEO_VIMEO)}
107
+ <div class="ons-cookies-banner ons-u-db"><button class="ons-js-accept-cookies">Accept</button></div>`,
108
+ );
109
+ await page.click('.ons-js-accept-cookies');
110
+
111
+ const src = await page.$eval('.ons-js-video-iframe', node => node.getAttribute('src'));
112
+ expect(src.includes('?dnt=1')).toBe(true);
113
+ }, 10000);
81
114
  });
82
115
  });