@ons/design-system 54.0.0 → 55.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 (69) hide show
  1. package/components/autosuggest/_autosuggest.scss +4 -4
  2. package/components/autosuggest/autosuggest.spec.js +12 -2
  3. package/components/autosuggest/autosuggest.ui.js +4 -7
  4. package/components/browser-banner/_macro.njk +1 -1
  5. package/components/browser-banner/_macro.spec.js +31 -0
  6. package/components/button/_button.scss +28 -7
  7. package/components/button/_macro.njk +1 -1
  8. package/components/button/_macro.spec.js +2 -2
  9. package/components/checkboxes/_checkbox.scss +50 -17
  10. package/components/collapsible/_collapsible.scss +2 -1
  11. package/components/document-list/document-list.scss +2 -0
  12. package/components/download-resources/download-resources.js +19 -0
  13. package/components/download-resources/download-resources.spec.js +95 -0
  14. package/components/external-link/_macro.njk +1 -1
  15. package/components/external-link/_macro.spec.js +2 -2
  16. package/components/fieldset/_fieldset.scss +11 -1
  17. package/components/fieldset/_macro.njk +9 -8
  18. package/components/fieldset/_macro.spec.js +27 -5
  19. package/components/footer/_footer.scss +1 -0
  20. package/components/footer/_macro.njk +1 -1
  21. package/components/footer/_macro.spec.js +18 -0
  22. package/components/header/_header.scss +7 -2
  23. package/components/header/_macro.njk +34 -8
  24. package/components/header/_macro.spec.js +82 -14
  25. package/components/hero/_macro.njk +1 -1
  26. package/components/hero/_macro.spec.js +1 -1
  27. package/components/icons/_macro.njk +1 -1
  28. package/components/input/_input-type.scss +37 -3
  29. package/components/input/_input.scss +28 -9
  30. package/components/input/_macro.njk +15 -17
  31. package/components/label/_label.scss +1 -1
  32. package/components/label/_macro.njk +27 -15
  33. package/components/label/_macro.spec.js +31 -0
  34. package/components/lists/_macro.njk +1 -1
  35. package/components/lists/_macro.spec.js +2 -2
  36. package/components/message/_message.scss +1 -0
  37. package/components/modal/_macro.njk +2 -2
  38. package/components/modal/_modal.scss +10 -9
  39. package/components/navigation/_macro.njk +1 -2
  40. package/components/navigation/_macro.spec.js +0 -1
  41. package/components/pagination/_pagination.scss +1 -0
  42. package/components/panel/_macro.njk +6 -9
  43. package/components/panel/_macro.spec.js +23 -20
  44. package/components/panel/_panel.scss +13 -5
  45. package/components/phase-banner/_macro.njk +1 -1
  46. package/components/phase-banner/_macro.spec.js +31 -0
  47. package/components/phase-banner/_phase-banner.scss +1 -0
  48. package/components/radios/_radio.scss +16 -4
  49. package/components/relationships/_relationships.scss +2 -2
  50. package/components/reply/_macro.njk +2 -2
  51. package/components/skip-to-content/_skip.scss +2 -1
  52. package/components/table/_macro.njk +3 -2
  53. package/components/table/_macro.spec.js +0 -27
  54. package/components/table/_table.scss +15 -7
  55. package/components/table/sortable-table.js +1 -0
  56. package/components/tabs/_tabs.scss +57 -34
  57. package/components/tabs/tabs.js +4 -2
  58. package/components/upload/_upload.scss +2 -2
  59. package/css/census.css +1 -1
  60. package/css/ids.css +1 -1
  61. package/css/main.css +1 -1
  62. package/layout/_template.njk +25 -12
  63. package/package.json +1 -1
  64. package/scripts/main.es5.js +1 -1
  65. package/scripts/main.js +1 -1
  66. package/scss/base/_global.scss +1 -0
  67. package/scss/overrides/hcm.scss +205 -46
  68. package/scss/patternlib.scss +1 -56
  69. package/scss/vars/_colors.scss +2 -1
@@ -11,7 +11,7 @@
11
11
  }
12
12
 
13
13
  &__results {
14
- border: 1px solid $color-input;
14
+ border: 1px solid $color-input-border;
15
15
  border-radius: $input-radius;
16
16
  display: none;
17
17
  margin: 0.5rem 0 0;
@@ -27,7 +27,7 @@
27
27
 
28
28
  &__results-title {
29
29
  background: $color-grey-15;
30
- border-bottom: 1px solid $color-input;
30
+ border-bottom: 1px solid $color-input-border;
31
31
  padding: 0.25rem 0.5rem;
32
32
  }
33
33
 
@@ -48,7 +48,7 @@
48
48
  padding: $input-padding-horizontal;
49
49
 
50
50
  &:not(:last-child) {
51
- border-bottom: 1px solid $color-input;
51
+ border-bottom: 1px solid $color-input-border;
52
52
  }
53
53
 
54
54
  &:not(&--no-results):not(&--more-results):hover,
@@ -87,7 +87,7 @@
87
87
  padding-left: 0.5rem;
88
88
 
89
89
  &:not(:last-child) {
90
- border-bottom: 1px solid $color-input;
90
+ border-bottom: 1px solid $color-input-border;
91
91
  }
92
92
  }
93
93
 
@@ -118,6 +118,16 @@ describe('script: autosuggest', () => {
118
118
  expect(ariaActiveDescendant).toBe(selectedOptionId);
119
119
  });
120
120
 
121
+ it('sets aria status to a message showing the selected result', async () => {
122
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
123
+
124
+ await page.type('.ons-js-autosuggest-input', 'Eng', { delay: 20 });
125
+ await page.keyboard.press('ArrowDown');
126
+
127
+ const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', node => node.textContent);
128
+ expect(statusMessage.trim()).toBe('England');
129
+ });
130
+
121
131
  it('does not mark other suggestions as being selected', async () => {
122
132
  await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
123
133
 
@@ -297,7 +307,7 @@ describe('script: autosuggest', () => {
297
307
 
298
308
  const attributes = await getNodeAttributes(page, '.ons-js-autosuggest-input');
299
309
  expect(attributes['aria-activedescendant']).toBeUndefined();
300
- expect(attributes['aria-expanded']).toBeUndefined();
310
+ expect(attributes['aria-expanded']).toBe('false');
301
311
  });
302
312
  });
303
313
 
@@ -502,7 +512,7 @@ describe('script: autosuggest', () => {
502
512
  await page.type('.ons-js-autosuggest-input', 'abc', { delay: 20 });
503
513
 
504
514
  const ariaExpandedValue = await page.$eval('.ons-js-autosuggest-input', node => node.getAttribute('aria-expanded'));
505
- expect(ariaExpandedValue).toBe(null);
515
+ expect(ariaExpandedValue).toBe('false');
506
516
  });
507
517
  });
508
518
  });
@@ -322,7 +322,7 @@ export default class AutosuggestUI {
322
322
  this.listbox.innerHTML = '';
323
323
  this.context.classList.remove(classAutosuggestHasResults);
324
324
  this.input.removeAttribute('aria-activedescendant');
325
- this.input.removeAttribute('aria-expanded');
325
+ this.input.setAttribute('aria-expanded', false);
326
326
 
327
327
  if (!preventAriaStatusUpdate) {
328
328
  this.setAriaStatus();
@@ -343,15 +343,12 @@ export default class AutosuggestUI {
343
343
  this.listbox.innerHTML = '';
344
344
  if (this.results) {
345
345
  this.resultOptions = this.results.map((result, index) => {
346
- let ariaLabel = result[this.lang];
347
- ariaLabel = ariaLabel.split('(<span class="ons-autosuggest-input__group">')[0];
348
346
  let innerHTML = this.emboldenMatch(result[this.lang], this.query);
349
347
 
350
348
  const listElement = document.createElement('li');
351
349
  listElement.className = classAutosuggestOption;
352
350
  listElement.setAttribute('id', `${this.listboxId}__option--${index}`);
353
351
  listElement.setAttribute('role', 'option');
354
- listElement.setAttribute('aria-label', ariaLabel);
355
352
  if (result.category) {
356
353
  innerHTML =
357
354
  innerHTML + `<span class="ons-autosuggest-input__category ons-u-lighter ons-u-fs-s ons-u-db">${result.category}</span>`;
@@ -437,13 +434,13 @@ export default class AutosuggestUI {
437
434
  option.setAttribute('aria-selected', true);
438
435
  this.input.setAttribute('aria-activedescendant', option.getAttribute('id'));
439
436
  const groupedResult = option.querySelector('.ons-autosuggest-input__group');
440
- const ariaLabel = option.getAttribute('aria-label');
437
+ const optionText = option.innerHTML.replace('<strong>', '').replace('</strong>', '');
441
438
  if (groupedResult) {
442
439
  let groupedAriaMsg = this.ariaGroupedResults.replace('{n}', groupedResult.innerHTML);
443
- groupedAriaMsg = groupedAriaMsg.replace('{x}', ariaLabel);
440
+ groupedAriaMsg = groupedAriaMsg.replace('{x}', optionText);
444
441
  this.setAriaStatus(groupedAriaMsg);
445
442
  } else {
446
- this.setAriaStatus(ariaLabel);
443
+ this.setAriaStatus(optionText);
447
444
  }
448
445
  } else {
449
446
  option.classList.remove(classAutosuggestOptionFocused);
@@ -10,7 +10,7 @@
10
10
  {% endif %}
11
11
 
12
12
  <div class="ons-browser-banner">
13
- <div class="ons-container{{ ' ons-container--wide' if params.wide is defined and params.wide }}">
13
+ <div class="ons-container{{ ' ons-container--full-width' if params.fullWidth }}{{ ' ons-container--wide' if params.wide }}">
14
14
  <p class="ons-browser-banner__content"><span class="ons-browser-banner__lead">{{ bannerLeadingText }}</span><span class="ons-browser-banner__cta"> {{ bannerCTA | safe }}</span></p>
15
15
  </div>
16
16
  </div>
@@ -49,6 +49,37 @@ describe('macro: browser-banner', () => {
49
49
 
50
50
  expect($('.ons-container').hasClass('ons-container--wide')).toBe(true);
51
51
  });
52
+
53
+ it('does not have `container--wide` class when `wide` is not set', () => {
54
+ const $ = cheerio.load(
55
+ renderComponent('browser-banner', {
56
+ ...EXAMPLE_BROWSER_BANNER_DEFAULT,
57
+ }),
58
+ );
59
+
60
+ expect($('.ons-container').hasClass('ons-container--wide')).toBe(false);
61
+ });
62
+
63
+ it('has `container--full-width` class when `fullWidth` is true', () => {
64
+ const $ = cheerio.load(
65
+ renderComponent('browser-banner', {
66
+ ...EXAMPLE_BROWSER_BANNER_DEFAULT,
67
+ fullWidth: true,
68
+ }),
69
+ );
70
+
71
+ expect($('.ons-container').hasClass('ons-container--full-width')).toBe(true);
72
+ });
73
+
74
+ it('does not have `container--full-width` class when `fullWidth` is not set', () => {
75
+ const $ = cheerio.load(
76
+ renderComponent('browser-banner', {
77
+ ...EXAMPLE_BROWSER_BANNER_DEFAULT,
78
+ }),
79
+ );
80
+
81
+ expect($('.ons-container').hasClass('ons-container--full-width')).toBe(false);
82
+ });
52
83
  });
53
84
 
54
85
  describe('mode: Welsh language', () => {
@@ -63,8 +63,11 @@ $button-shadow-size: 3px;
63
63
  }
64
64
 
65
65
  // When focused
66
- &:focus & {
66
+ &:focus,
67
+ &:focus-visible {
68
+ // Add transparent outline because Windows High Contrast Mode doesn't show box-shadows
67
69
  outline: 3px solid transparent;
70
+ outline-offset: 1px;
68
71
  }
69
72
 
70
73
  &:focus &__inner {
@@ -91,11 +94,6 @@ $button-shadow-size: 3px;
91
94
  top: ems($button-shadow-size);
92
95
  }
93
96
 
94
- &:focus,
95
- &:focus:hover {
96
- outline: none;
97
- }
98
-
99
97
  // Small buttons
100
98
  &--small,
101
99
  &--mobile {
@@ -170,6 +168,8 @@ $button-shadow-size: 3px;
170
168
 
171
169
  &--link:focus:not(:active):not(&--secondary) &,
172
170
  &--link:focus:hover:not(:active):not(&--secondary) & {
171
+ outline: inherit;
172
+
173
173
  &__inner {
174
174
  .ons-svg-icon {
175
175
  fill: $color-text;
@@ -386,13 +386,20 @@ $button-shadow-size: 3px;
386
386
  &--ghost-dark:focus &,
387
387
  &--dropdown:focus & {
388
388
  &__inner {
389
- box-shadow: none;
389
+ border-color: $color-text-link-focus;
390
+ box-shadow: 0 0 0 1px $color-text-link-focus;
390
391
  .ons-svg-icon {
391
392
  fill: $color-black;
392
393
  }
393
394
  }
394
395
  }
395
396
 
397
+ &--dropdown:focus & {
398
+ &__inner {
399
+ box-shadow: inset 0 -4px 0 0 $color-text-link-focus;
400
+ }
401
+ }
402
+
396
403
  &--mobile[aria-expanded='true'],
397
404
  &--text-link[aria-expanded='true'] {
398
405
  .ons-svg-icon {
@@ -473,3 +480,17 @@ $button-shadow-size: 3px;
473
480
  }
474
481
  }
475
482
  }
483
+
484
+ .ons-btn-group {
485
+ @extend .ons-u-mb-m;
486
+
487
+ align-items: baseline;
488
+ display: flex;
489
+ flex-direction: row;
490
+ flex-wrap: wrap;
491
+
492
+ & .ons-btn,
493
+ & a {
494
+ margin: 0 1rem 1rem 0;
495
+ }
496
+ }
@@ -86,7 +86,7 @@
86
86
  {% endif -%}
87
87
  </span>
88
88
  {% if params.url is defined and params.url and params.newWindow is defined and params.newWindow %}
89
- <span class="ons-btn__new-window-description ons-u-vh">({{ params.newWindowDescription | default("opens in a new tab") }})</span>
89
+ <span class="ons-btn__new-window-description ons-u-vh"> ({{ params.newWindowDescription | default("opens in a new tab") }})</span>
90
90
  {% endif %}
91
91
  {% if params.buttonContext is defined and params.buttonContext %}
92
92
  <span class="ons-btn__context ons-u-vh">{{ params.buttonContext }}</span>
@@ -407,7 +407,7 @@ describe('macro: button', () => {
407
407
  }),
408
408
  );
409
409
 
410
- expect($('.ons-btn__new-window-description').text()).toBe('(opens in a new tab)');
410
+ expect($('.ons-btn__new-window-description').text()).toBe(' (opens in a new tab)');
411
411
  });
412
412
 
413
413
  it('has a custom new window description when `newWindow` is `true` and `newWindowDescription` is provided', () => {
@@ -419,7 +419,7 @@ describe('macro: button', () => {
419
419
  }),
420
420
  );
421
421
 
422
- expect($('.ons-btn__new-window-description').text()).toBe('(custom opens in a new window text)');
422
+ expect($('.ons-btn__new-window-description').text()).toBe(' (custom opens in a new window text)');
423
423
  });
424
424
 
425
425
  it('has the `download` attribute when `buttonStyle` is "download"', () => {
@@ -9,12 +9,11 @@ $checkbox-padding: 11px;
9
9
 
10
10
  &__input {
11
11
  appearance: none;
12
- background: url(#{$static}/img/icons--check.svg) no-repeat center center;
13
- background-color: $color-white;
14
- background-size: 0;
15
- border: 2px solid $color-input;
12
+ background-color: $color-input-bg;
13
+ border: 2px solid $color-input-border;
16
14
  border-radius: 0.2rem;
17
15
  box-sizing: border-box;
16
+ cursor: pointer;
18
17
  height: $checkbox-input-width;
19
18
  left: $checkbox-padding;
20
19
  position: absolute;
@@ -22,13 +21,30 @@ $checkbox-padding: 11px;
22
21
  width: $checkbox-input-width;
23
22
  z-index: 1;
24
23
 
24
+ // Check icon
25
+ &::after {
26
+ border: solid $color-input-border;
27
+ border-radius: 1px;
28
+ border-top-color: $color-input-bg;
29
+ border-width: 0 0 3px 3px;
30
+ box-sizing: border-box;
31
+ content: '';
32
+ height: 7px;
33
+ left: 2px;
34
+ opacity: 0;
35
+ position: absolute;
36
+ top: 4px;
37
+ transform: rotate(-45deg);
38
+ width: 14px;
39
+ }
40
+
25
41
  &:focus,
26
42
  &:checked {
27
43
  outline: none;
28
44
  }
29
45
 
30
- &:checked {
31
- background-size: 14px;
46
+ &:checked::after {
47
+ opacity: 1;
32
48
  }
33
49
 
34
50
  &:disabled {
@@ -36,9 +52,24 @@ $checkbox-padding: 11px;
36
52
  cursor: not-allowed;
37
53
  }
38
54
 
39
- &:disabled + label {
40
- color: $color-grey-35;
55
+ &:disabled:checked::after {
56
+ border-color: $color-border-disabled;
57
+ }
58
+
59
+ &:disabled + .ons-checkbox__label,
60
+ &:disabled:checked + .ons-checkbox__label {
61
+ color: $color-border-disabled;
41
62
  cursor: not-allowed;
63
+
64
+ &::before {
65
+ border: 1px solid $color-border-disabled;
66
+ }
67
+ }
68
+
69
+ &:disabled:checked + .ons-checkbox__label {
70
+ &::before {
71
+ box-shadow: 0 0 0 1px $color-border-disabled;
72
+ }
42
73
  }
43
74
  }
44
75
 
@@ -47,9 +78,9 @@ $checkbox-padding: 11px;
47
78
  padding: 0 0 0 1.85rem;
48
79
 
49
80
  &::before {
50
- background: none;
51
- border: none;
52
- box-shadow: none;
81
+ background: none !important;
82
+ border: none !important;
83
+ box-shadow: none !important;
53
84
  }
54
85
 
55
86
  & > .ons-checkbox__label--with-description {
@@ -69,11 +100,12 @@ $checkbox-padding: 11px;
69
100
  background: none;
70
101
  border: none;
71
102
  box-shadow: none;
103
+ outline: none;
72
104
  }
73
105
  }
74
106
 
75
107
  &:focus {
76
- box-shadow: 0 0 0 3px $color-focus;
108
+ @extend %ons-input-focus;
77
109
  }
78
110
  }
79
111
 
@@ -101,7 +133,7 @@ $checkbox-padding: 11px;
101
133
  }
102
134
 
103
135
  &:focus {
104
- box-shadow: 0 0 0 3px $color-focus;
136
+ @extend %ons-input-focus;
105
137
  }
106
138
 
107
139
  & + .ons-checkbox__label {
@@ -122,7 +154,7 @@ $checkbox-padding: 11px;
122
154
 
123
155
  &::before {
124
156
  background: $color-white;
125
- border: 1px solid $color-input;
157
+ border: 1px solid $color-input-border;
126
158
  border-radius: 3px;
127
159
  bottom: 0;
128
160
  content: '';
@@ -152,7 +184,8 @@ $checkbox-padding: 11px;
152
184
 
153
185
  &__input:checked + &__label::before {
154
186
  background: $color-grey-5;
155
- box-shadow: 0 0 0 1px $color-input;
187
+ box-shadow: 0 0 0 1px $color-input-border;
188
+ outline: 1px solid transparent; // Add transparent outline because Windows High Contrast Mode doesn't show box-shadows
156
189
  }
157
190
 
158
191
  .ons-panel--error .ons-radio__input:checked ~ &__other > .ons-input--text:required:not(:focus) {
@@ -176,10 +209,10 @@ $checkbox-padding: 11px;
176
209
  &--toggle & {
177
210
  &__input {
178
211
  left: 0;
179
- top: 0.1rem;
212
+ top: 0.2rem;
180
213
 
181
214
  &:focus {
182
- box-shadow: 0 0 0 3px $color-focus;
215
+ @extend %ons-input-focus;
183
216
  }
184
217
  }
185
218
 
@@ -10,7 +10,8 @@ $collapsible-caret-width: 1.5rem;
10
10
  pointer-events: initial;
11
11
  position: relative;
12
12
 
13
- &::marker {
13
+ &::marker,
14
+ &::-webkit-details-marker {
14
15
  display: none;
15
16
  }
16
17
 
@@ -120,6 +120,8 @@
120
120
  background-color: $color-banner-bg;
121
121
  border-bottom: none;
122
122
  display: block;
123
+ outline: 2px solid transparent; // Add transparent outline because Windows High Contrast Mode doesn't show background
124
+ outline-offset: -2px;
123
125
  padding: 2rem;
124
126
 
125
127
  @include mq(m) {
@@ -1061,9 +1061,28 @@ Math.easeInOutQuad = function(t, b, c, d) {
1061
1061
 
1062
1062
  // Toggle filters visibility on small devices
1063
1063
  function toggleFilters(bool) {
1064
+ let resultsOptions = document.getElementsByClassName('ons-adv-filter__results-options')[0];
1065
+ let resultsList = document.getElementsByClassName('ons-js-adv-filter__gallery')[0];
1066
+ let header = document.getElementsByClassName('ons-header')[0];
1067
+ let breadcrumbs = document.getElementsByClassName('ons-breadcrumb')[0];
1068
+ let footer = document.getElementsByClassName('ons-footer')[0];
1069
+
1064
1070
  Util.toggleClass(filtersPanel, 'ons-adv-filter__panel--is-visible', bool);
1065
1071
  Util.toggleClass(body, 'ons-no-scroll', bool);
1066
1072
  filtersTrigger.setAttribute('aria-expanded', bool);
1073
+ filtersTrigger.setAttribute('aria-hidden', bool);
1074
+ Util.toggleClass(filtersTrigger, 'ons-u-d-no', bool);
1075
+
1076
+ Util.toggleClass(resultsOptions, 'ons-u-d-no', bool);
1077
+ Util.toggleClass(resultsList, 'ons-u-d-no', bool);
1078
+ Util.toggleClass(header, 'ons-u-d-no', bool);
1079
+ Util.toggleClass(breadcrumbs, 'ons-u-d-no', bool);
1080
+ Util.toggleClass(footer, 'ons-u-d-no', bool);
1081
+ resultsOptions.setAttribute('aria-hidden', bool);
1082
+ resultsList.setAttribute('aria-hidden', bool);
1083
+ header.setAttribute('aria-hidden', bool);
1084
+ breadcrumbs.setAttribute('aria-hidden', bool);
1085
+ footer.setAttribute('aria-hidden', bool);
1067
1086
  }
1068
1087
  }
1069
1088
  })();
@@ -4,6 +4,20 @@ import { setViewport } from '../../tests/helpers/puppeteer';
4
4
  import { renderComponent, renderTemplate, setTestPage } from '../../tests/helpers/rendering';
5
5
 
6
6
  const EXAMPLE_PAGE = `
7
+ ${renderComponent('header', {})}
8
+ ${renderComponent('breadcrumbs', {
9
+ ariaLabel: 'Breadcrumbs',
10
+ itemsList: [
11
+ {
12
+ url: '/',
13
+ text: 'Home',
14
+ },
15
+ {
16
+ url: '/components',
17
+ text: 'Components',
18
+ },
19
+ ],
20
+ })}
7
21
  <div class="ons-js-adv-filter">
8
22
  ${renderComponent('button', {
9
23
  type: 'button',
@@ -175,6 +189,7 @@ const EXAMPLE_PAGE = `
175
189
  <p>Try selecting different filters to get results.</p>
176
190
  </div>
177
191
  </div>
192
+ ${renderComponent('footer', {})}
178
193
  `;
179
194
 
180
195
  const RENDERED_EXAMPLE_PAGE = renderTemplate(EXAMPLE_PAGE);
@@ -505,6 +520,32 @@ describe('script: download-resources', () => {
505
520
  expect(displayStyle).not.toBe('none');
506
521
  });
507
522
 
523
+ it('hides the underlying page elements when the "Show filters" button is pressed', async () => {
524
+ await page.click('.ons-js-adv-filter__trigger');
525
+
526
+ const isListHiddenClass = await page.$eval('.ons-js-adv-filter__gallery', node => node.classList.contains('ons-u-d-no'));
527
+ const isListAriaHidden = await page.$eval('.ons-js-adv-filter__gallery', node => node.getAttribute('aria-hidden'));
528
+ const isOptionsHiddenClass = await page.$eval('.ons-adv-filter__results-options', node => node.classList.contains('ons-u-d-no'));
529
+ const isOptionsAriaHidden = await page.$eval('.ons-adv-filter__results-options', node => node.getAttribute('aria-hidden'));
530
+ const isHeaderHiddenClass = await page.$eval('.ons-header', node => node.classList.contains('ons-u-d-no'));
531
+ const isHeaderAriaHidden = await page.$eval('.ons-header', node => node.getAttribute('aria-hidden'));
532
+ const isFooterHiddenClass = await page.$eval('.ons-footer', node => node.classList.contains('ons-u-d-no'));
533
+ const isFooterAriaHidden = await page.$eval('.ons-footer', node => node.getAttribute('aria-hidden'));
534
+ const isBreadcrumbsHiddenClass = await page.$eval('.ons-breadcrumb', node => node.classList.contains('ons-u-d-no'));
535
+ const isBreadcrumbsAriaHidden = await page.$eval('.ons-breadcrumb', node => node.getAttribute('aria-hidden'));
536
+
537
+ expect(isListHiddenClass).toBe(true);
538
+ expect(isListAriaHidden).toBe('true');
539
+ expect(isOptionsHiddenClass).toBe(true);
540
+ expect(isOptionsAriaHidden).toBe('true');
541
+ expect(isHeaderHiddenClass).toBe(true);
542
+ expect(isHeaderAriaHidden).toBe('true');
543
+ expect(isFooterHiddenClass).toBe(true);
544
+ expect(isFooterAriaHidden).toBe('true');
545
+ expect(isBreadcrumbsHiddenClass).toBe(true);
546
+ expect(isBreadcrumbsAriaHidden).toBe('true');
547
+ });
548
+
508
549
  it('hides filter elements when the "Show (n results)" button is pressed', async () => {
509
550
  await page.click('.ons-js-adv-filter__trigger');
510
551
  await page.click('.ons-js-adv-filter__show');
@@ -513,6 +554,33 @@ describe('script: download-resources', () => {
513
554
  expect(displayStyle).toBe('none');
514
555
  });
515
556
 
557
+ it('shows the underlying page elements when the "Show (n results)" button is pressed', async () => {
558
+ await page.click('.ons-js-adv-filter__trigger');
559
+ await page.click('.ons-js-adv-filter__show');
560
+
561
+ const isListHiddenClass = await page.$eval('.ons-js-adv-filter__gallery', node => node.classList.contains('ons-u-d-no'));
562
+ const isListAriaHidden = await page.$eval('.ons-js-adv-filter__gallery', node => node.getAttribute('aria-hidden'));
563
+ const isOptionsHiddenClass = await page.$eval('.ons-adv-filter__results-options', node => node.classList.contains('ons-u-d-no'));
564
+ const isOptionsAriaHidden = await page.$eval('.ons-adv-filter__results-options', node => node.getAttribute('aria-hidden'));
565
+ const isHeaderHiddenClass = await page.$eval('.ons-header', node => node.classList.contains('ons-u-d-no'));
566
+ const isHeaderAriaHidden = await page.$eval('.ons-header', node => node.getAttribute('aria-hidden'));
567
+ const isFooterHiddenClass = await page.$eval('.ons-footer', node => node.classList.contains('ons-u-d-no'));
568
+ const isFooterAriaHidden = await page.$eval('.ons-footer', node => node.getAttribute('aria-hidden'));
569
+ const isBreadcrumbsHiddenClass = await page.$eval('.ons-breadcrumb', node => node.classList.contains('ons-u-d-no'));
570
+ const isBreadcrumbsAriaHidden = await page.$eval('.ons-breadcrumb', node => node.getAttribute('aria-hidden'));
571
+
572
+ expect(isListHiddenClass).toBe(false);
573
+ expect(isListAriaHidden).toBe('false');
574
+ expect(isOptionsHiddenClass).toBe(false);
575
+ expect(isOptionsAriaHidden).toBe('false');
576
+ expect(isHeaderHiddenClass).toBe(false);
577
+ expect(isHeaderAriaHidden).toBe('false');
578
+ expect(isFooterHiddenClass).toBe(false);
579
+ expect(isFooterAriaHidden).toBe('false');
580
+ expect(isBreadcrumbsHiddenClass).toBe(false);
581
+ expect(isBreadcrumbsAriaHidden).toBe('false');
582
+ });
583
+
516
584
  it('hides filter elements when the "Close" button is pressed', async () => {
517
585
  await page.click('.ons-js-adv-filter__trigger');
518
586
  await page.click('.ons-js-adv-filter__close');
@@ -520,6 +588,33 @@ describe('script: download-resources', () => {
520
588
  const displayStyle = await page.$eval('.ons-adv-filter__panel', node => getComputedStyle(node).display);
521
589
  expect(displayStyle).toBe('none');
522
590
  });
591
+
592
+ it('shows the underlying page elements when the "Close" button is pressed', async () => {
593
+ await page.click('.ons-js-adv-filter__trigger');
594
+ await page.click('.ons-js-adv-filter__close');
595
+
596
+ const isListHiddenClass = await page.$eval('.ons-js-adv-filter__gallery', node => node.classList.contains('ons-u-d-no'));
597
+ const isListAriaHidden = await page.$eval('.ons-js-adv-filter__gallery', node => node.getAttribute('aria-hidden'));
598
+ const isOptionsHiddenClass = await page.$eval('.ons-adv-filter__results-options', node => node.classList.contains('ons-u-d-no'));
599
+ const isOptionsAriaHidden = await page.$eval('.ons-adv-filter__results-options', node => node.getAttribute('aria-hidden'));
600
+ const isHeaderHiddenClass = await page.$eval('.ons-header', node => node.classList.contains('ons-u-d-no'));
601
+ const isHeaderAriaHidden = await page.$eval('.ons-header', node => node.getAttribute('aria-hidden'));
602
+ const isFooterHiddenClass = await page.$eval('.ons-footer', node => node.classList.contains('ons-u-d-no'));
603
+ const isFooterAriaHidden = await page.$eval('.ons-footer', node => node.getAttribute('aria-hidden'));
604
+ const isBreadcrumbsHiddenClass = await page.$eval('.ons-breadcrumb', node => node.classList.contains('ons-u-d-no'));
605
+ const isBreadcrumbsAriaHidden = await page.$eval('.ons-breadcrumb', node => node.getAttribute('aria-hidden'));
606
+
607
+ expect(isListHiddenClass).toBe(false);
608
+ expect(isListAriaHidden).toBe('false');
609
+ expect(isOptionsHiddenClass).toBe(false);
610
+ expect(isOptionsAriaHidden).toBe('false');
611
+ expect(isHeaderHiddenClass).toBe(false);
612
+ expect(isHeaderAriaHidden).toBe('false');
613
+ expect(isFooterHiddenClass).toBe(false);
614
+ expect(isFooterAriaHidden).toBe('false');
615
+ expect(isBreadcrumbsHiddenClass).toBe(false);
616
+ expect(isBreadcrumbsAriaHidden).toBe('false');
617
+ });
523
618
  });
524
619
  });
525
620
 
@@ -6,5 +6,5 @@
6
6
  </span><span class="ons-external-link__icon">&nbsp;<svg class="ons-svg-icon" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg" focusable="false" aria-hidden="true">
7
7
  <path d="M13.5,9H13a.5.5,0,0,0-.5.5v3h-9v-9h3A.5.5,0,0,0,7,3V2.5A.5.5,0,0,0,6.5,2h-4a.5.5,0,0,0-.5.5v11a.5.5,0,0,0,.5.5h11a.5.5,0,0,0,.5-.5v-4A.5.5,0,0,0,13.5,9Z" transform="translate(-2 -1.99)"/>
8
8
  <path d="M8.83,7.88a.51.51,0,0,0,.71,0l2.31-2.32,1.28,1.28A.51.51,0,0,0,14,6.49v-4a.52.52,0,0,0-.5-.5h-4A.51.51,0,0,0,9,2.52a.58.58,0,0,0,.14.33l1.28,1.28L8.12,6.46a.51.51,0,0,0,0,.71Z" transform="translate(-2 -1.99)"/>
9
- </svg></span><span class="ons-external-link__new-window-description ons-u-vh">({{- params.newWindowDescription | default("opens in a new tab") -}})</span></a>
9
+ </svg></span><span class="ons-external-link__new-window-description ons-u-vh"> ({{- params.newWindowDescription | default("opens in a new tab") -}})</span></a>
10
10
  {% endmacro %}
@@ -54,7 +54,7 @@ describe('macro: external-link', () => {
54
54
  it('has a default new window description', async () => {
55
55
  const $ = cheerio.load(renderComponent('external-link', EXAMPLE_EXTERNAL_LINK));
56
56
 
57
- expect($('.ons-external-link__new-window-description').text()).toBe('(opens in a new tab)');
57
+ expect($('.ons-external-link__new-window-description').text()).toBe(' (opens in a new tab)');
58
58
  });
59
59
 
60
60
  it('has a custom new window description when `newWindowDescription` is provided', () => {
@@ -65,7 +65,7 @@ describe('macro: external-link', () => {
65
65
  }),
66
66
  );
67
67
 
68
- expect($('.ons-external-link__new-window-description').text()).toBe('(custom opens in a new tab text)');
68
+ expect($('.ons-external-link__new-window-description').text()).toBe(' (custom opens in a new tab text)');
69
69
  });
70
70
 
71
71
  it('has an "external-link" icon', async () => {
@@ -1,11 +1,21 @@
1
1
  .ons-fieldset {
2
2
  &__legend {
3
3
  font-weight: $font-weight-bold;
4
- margin: 0 0 0.6rem;
4
+ margin: 0;
5
+ &:not(&--with-description) {
6
+ margin-bottom: 0.55rem;
7
+ }
8
+ &-title {
9
+ display: block;
10
+ margin: 0;
11
+ padding: 0 0 1.5rem;
12
+ }
5
13
  }
6
14
 
7
15
  &__description:not(&__description--title) {
8
16
  @extend .ons-label__description;
17
+
18
+ margin-bottom: 0.55rem;
9
19
  }
10
20
 
11
21
  &__description--title {