@ons/design-system 63.0.0 → 65.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.
Files changed (110) 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/breadcrumbs/_breadcrumbs.scss +6 -6
  13. package/components/breadcrumbs/_macro.njk +4 -4
  14. package/components/breadcrumbs/_macro.spec.js +13 -13
  15. package/components/button/_button.scss +27 -27
  16. package/components/button/_macro.spec.js +2 -2
  17. package/components/call-to-action/_macro.njk +1 -1
  18. package/components/char-check-limit/_macro.njk +1 -1
  19. package/components/char-check-limit/_macro.spec.js +1 -1
  20. package/components/char-check-limit/character-check.spec.js +16 -16
  21. package/components/checkboxes/_macro.njk +3 -1
  22. package/components/checkboxes/example-checkboxes-with-descriptions.njk +1 -0
  23. package/components/cookies-banner/_macro.njk +2 -2
  24. package/components/cookies-banner/_macro.spec.js +2 -2
  25. package/components/date-input/_macro.njk +3 -3
  26. package/components/date-input/_macro.spec.js +118 -0
  27. package/components/date-input/example-date-input-error-for-single-field.njk +63 -0
  28. package/components/details/_details.scss +1 -1
  29. package/components/external-link/_external-link.scss +3 -3
  30. package/components/external-link/_macro.njk +1 -1
  31. package/components/footer/_footer.scss +2 -2
  32. package/components/footer/example-footer-with-alternative-organisation.njk +5 -5
  33. package/components/header/_header.scss +8 -8
  34. package/components/icon/_icon.scss +1 -1
  35. package/components/icon/_macro.njk +35 -35
  36. package/components/icon/_macro.spec.js +1 -1
  37. package/components/image/_image.scss +2 -2
  38. package/components/image/_macro.njk +4 -6
  39. package/components/image/_macro.spec.js +10 -10
  40. package/components/input/_input.scss +6 -0
  41. package/components/input/_macro.njk +20 -13
  42. package/components/input/_macro.spec.js +2 -22
  43. package/components/{search/example-search-with-character-check.njk → input/example-input-search-with-character-check.njk} +1 -2
  44. package/components/{search/example-search-with-placeholder.njk → input/example-input-search-with-placeholder.njk} +1 -2
  45. package/components/{search/example-search.njk → input/example-input-search.njk} +1 -2
  46. package/components/mutually-exclusive/_macro.njk +4 -3
  47. package/components/mutually-exclusive/mutually-exclusive.textarea.spec.js +1 -1
  48. package/components/pagination/_macro.njk +2 -2
  49. package/components/pagination/example-pagination-first.njk +0 -2
  50. package/components/pagination/example-pagination-last.njk +0 -2
  51. package/components/pagination/example-pagination-with-no-range-indicator.njk +0 -2
  52. package/components/pagination/example-pagination.njk +0 -2
  53. package/components/panel/_macro.njk +1 -1
  54. package/components/panel/_panel.scss +7 -7
  55. package/components/password/_macro.njk +1 -1
  56. package/components/password/example-password.njk +1 -2
  57. package/components/quote/_quote.scss +1 -1
  58. package/components/radios/_macro.njk +1 -1
  59. package/components/select/_macro.njk +1 -2
  60. package/components/skip-to-content/_macro.njk +2 -1
  61. package/components/skip-to-content/_macro.spec.js +17 -3
  62. package/components/skip-to-content/_skip.scss +1 -1
  63. package/components/skip-to-content/skip-to-content.dom.js +1 -1
  64. package/components/skip-to-content/skip-to-content.spec.js +3 -3
  65. package/components/summary/_macro.njk +1 -2
  66. package/components/summary/_macro.spec.js +7 -22
  67. package/components/summary/_summary.scss +1 -1
  68. package/components/summary/example-summary-grouped-total.njk +0 -2
  69. package/components/summary/example-summary-grouped-with-errors.njk +0 -4
  70. package/components/summary/example-summary-grouped.njk +0 -19
  71. package/components/summary/example-summary-household.njk +0 -5
  72. package/components/summary/example-summary-hub.njk +0 -8
  73. package/components/summary/example-summary-multiple.njk +0 -4
  74. package/components/summary/example-summary.njk +0 -4
  75. package/components/table/_macro.njk +1 -1
  76. package/components/table/_macro.spec.js +16 -0
  77. package/components/table/_table.scss +6 -6
  78. package/components/table/example-table-numeric.njk +6 -3
  79. package/components/table/sortable-table.js +1 -1
  80. package/components/tabs/_macro.njk +4 -3
  81. package/components/tabs/_macro.spec.js +23 -0
  82. package/components/tabs/_tabs.scss +11 -15
  83. package/components/tabs/example-tabs.njk +6 -6
  84. package/components/tabs/tabs.js +24 -8
  85. package/components/tabs/tabs.spec.js +40 -2
  86. package/components/textarea/_macro.njk +2 -2
  87. package/components/textarea/_macro.spec.js +2 -2
  88. package/components/textarea/textarea.spec.js +6 -10
  89. package/components/timeline/_macro.njk +18 -22
  90. package/components/timeline/_macro.spec.js +18 -0
  91. package/components/video/example-video.njk +1 -1
  92. package/components/video/video.js +10 -1
  93. package/components/video/video.spec.js +33 -0
  94. package/css/main.css +3 -3
  95. package/css/print.css +1 -1
  96. package/js/main.js +1 -1
  97. package/package.json +1 -1
  98. package/scripts/main.es5.js +1 -1
  99. package/scripts/main.js +1 -1
  100. package/scss/base/_global.scss +1 -1
  101. package/scss/main.scss +1 -2
  102. package/scss/objects/_spacing.scss +3 -3
  103. package/scss/overrides/hcm.scss +6 -6
  104. package/scss/overrides/rtl.scss +2 -2
  105. package/scss/print.scss +1 -1
  106. package/components/access-code/uac.dom.js +0 -11
  107. package/components/search/_macro.njk +0 -30
  108. package/components/search/_macro.spec.js +0 -69
  109. package/components/search/_search.scss +0 -9
  110. /package/components/access-code/{uac.spec.js → access-code.spec.js} +0 -0
@@ -9,6 +9,7 @@ const EXAMPLE_TABS = {
9
9
  {
10
10
  id: 'tab.id.1',
11
11
  title: 'Tab 1',
12
+ showTitle: true,
12
13
  content: 'First content...',
13
14
  },
14
15
  {
@@ -24,6 +25,38 @@ const EXAMPLE_TABS = {
24
25
  ],
25
26
  };
26
27
 
28
+ const EXAMPLE_TABS_LONGER = {
29
+ title: 'Example tabs',
30
+ tabs: [
31
+ {
32
+ id: 'tab.id.1',
33
+ title: 'Tab 1',
34
+ showTitle: true,
35
+ content: 'First content...',
36
+ },
37
+ {
38
+ id: 'tab.id.2',
39
+ title: 'Tab 2',
40
+ content: 'Second content...',
41
+ },
42
+ {
43
+ id: 'tab.id.3',
44
+ title: 'Tab 3',
45
+ content: 'Third content...',
46
+ },
47
+ {
48
+ id: 'tab.id.4',
49
+ title: 'Tab 4',
50
+ content: 'Fourth content...',
51
+ },
52
+ {
53
+ id: 'tab.id.5',
54
+ title: 'Tab 5',
55
+ content: 'Fifth content...',
56
+ },
57
+ ],
58
+ };
59
+
27
60
  const EXAMPLE_TABS_WITH_NO_INITIAL_ACTIVE_TAB = {
28
61
  ...EXAMPLE_TABS,
29
62
  noInitialActiveTab: true,
@@ -175,7 +208,7 @@ describe('script: tabs', () => {
175
208
  beforeEach(async () => {
176
209
  await page.emulate(puppeteer.devices['iPhone X']);
177
210
 
178
- await setTestPage('/test', renderComponent('tabs', EXAMPLE_TABS));
211
+ await setTestPage('/test', renderComponent('tabs', EXAMPLE_TABS_LONGER));
179
212
  });
180
213
 
181
214
  it('has no aria attributes on tabs', async () => {
@@ -194,11 +227,16 @@ describe('script: tabs', () => {
194
227
 
195
228
  it('has no hidden tab panels', async () => {
196
229
  const panelCount = await page.$$eval('.ons-tabs__panel', nodes => nodes.length);
197
- expect(panelCount).toBe(3);
230
+ expect(panelCount).toBe(5);
198
231
 
199
232
  const hiddenPanelCount = await page.$$eval('.ons-tabs__panel--hidden', nodes => nodes.length);
200
233
  expect(hiddenPanelCount).toBe(0);
201
234
  });
235
+
236
+ it('displays a h2 element with a unique id', async () => {
237
+ const panelCount = await page.$$eval('#tab-1-content-title', nodes => nodes.length);
238
+ expect(panelCount).toBe(1);
239
+ });
202
240
  });
203
241
 
204
242
  describe('when `data-no-initial-active-tab` is present', () => {
@@ -26,8 +26,8 @@
26
26
  rows="{{ params.rows | default(8) }}"
27
27
  {% if params.charCheckLimit and params.charCheckLimit.limit %}
28
28
  maxlength="{{ params.charCheckLimit.limit }}"
29
- data-char-limit-ref="{{ params.id }}-lim-remaining"
30
- aria-describedby="{{ params.id }}-lim-remaining"
29
+ data-char-limit-ref="{{ params.id }}-lim"
30
+ aria-describedby="{{ params.id }}-lim"
31
31
  {% endif %}
32
32
  {% if params.attributes %}{% for attribute, value in (params.attributes.items() if params.attributes is mapping and params.attributes.items else params.attributes) %}{{ attribute }}{% if value %}="{{ value }}"{% endif %} {% endfor %}{% endif %}
33
33
  >{{ params.value if params.value }}</textarea>
@@ -216,13 +216,13 @@ describe('macro: textarea', () => {
216
216
  it('has data attribute which references the character limit component', () => {
217
217
  const $ = cheerio.load(renderComponent('textarea', EXAMPLE_TEXTAREA_WITH_CHARACTER_LIMIT));
218
218
 
219
- expect($('.ons-input--textarea').attr('data-char-limit-ref')).toBe('example-id-lim-remaining');
219
+ expect($('.ons-input--textarea').attr('data-char-limit-ref')).toBe('example-id-lim');
220
220
  });
221
221
 
222
222
  it('has `aria-describedby` attribute which references the character limit component', () => {
223
223
  const $ = cheerio.load(renderComponent('textarea', EXAMPLE_TEXTAREA_WITH_CHARACTER_LIMIT));
224
224
 
225
- expect($('.ons-input--textarea').attr('aria-describedby')).toBe('example-id-lim-remaining');
225
+ expect($('.ons-input--textarea').attr('aria-describedby')).toBe('example-id-lim');
226
226
  });
227
227
 
228
228
  it('renders character limit component', () => {
@@ -24,7 +24,7 @@ describe('script: textarea', () => {
24
24
 
25
25
  describe('Given that the char limit helper has initialised correctly', () => {
26
26
  it('the char limit readout should be visible', async () => {
27
- const hasClass = await page.$eval('#example-textarea-lim-remaining', node => node.classList.contains('ons-u-d-no'));
27
+ const hasClass = await page.$eval('#example-textarea-lim', node => node.classList.contains('ons-u-d-no'));
28
28
  expect(hasClass).toBe(false);
29
29
  });
30
30
  });
@@ -36,7 +36,7 @@ describe('script: textarea', () => {
36
36
  });
37
37
 
38
38
  it('then the characters remaining readout reflect the number of characters remaining', async () => {
39
- const readout = await page.$eval('#example-textarea-lim-remaining', node => node.textContent);
39
+ const readout = await page.$eval('#example-textarea-lim', node => node.textContent);
40
40
  expect(readout).toBe('You have 12 characters remaining');
41
41
  });
42
42
  });
@@ -47,7 +47,7 @@ describe('script: textarea', () => {
47
47
  });
48
48
 
49
49
  it('then the characters remaining readout reflect the number of characters remaining', async () => {
50
- const readout = await page.$eval('#example-textarea-lim-remaining', node => node.textContent);
50
+ const readout = await page.$eval('#example-textarea-lim', node => node.textContent);
51
51
  expect(readout).toBe('You have 0 characters remaining');
52
52
  });
53
53
 
@@ -57,9 +57,7 @@ describe('script: textarea', () => {
57
57
  });
58
58
 
59
59
  it('then the readout should be given limit reached classes', async () => {
60
- const hasClass = await page.$eval('#example-textarea-lim-remaining', node =>
61
- node.classList.contains('ons-input__limit--reached'),
62
- );
60
+ const hasClass = await page.$eval('#example-textarea-lim', node => node.classList.contains('ons-input__limit--reached'));
63
61
  expect(hasClass).toBe(true);
64
62
  });
65
63
  });
@@ -77,7 +75,7 @@ describe('script: textarea', () => {
77
75
  });
78
76
 
79
77
  it('then the characters remaining readout reflect the number of characters remaining', async () => {
80
- const readout = await page.$eval('#example-textarea-lim-remaining', node => node.textContent);
78
+ const readout = await page.$eval('#example-textarea-lim', node => node.textContent);
81
79
  expect(readout).toBe('You have 1 character remaining');
82
80
  });
83
81
 
@@ -87,9 +85,7 @@ describe('script: textarea', () => {
87
85
  });
88
86
 
89
87
  it('then the readout should not be given limit reached classes', async () => {
90
- const hasClass = await page.$eval('#example-textarea-lim-remaining', node =>
91
- node.classList.contains('ons-input__limit--reached'),
92
- );
88
+ const hasClass = await page.$eval('#example-textarea-lim', node => node.classList.contains('ons-input__limit--reached'));
93
89
  expect(hasClass).toBe(false);
94
90
  });
95
91
  });
@@ -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
  });