@ons/design-system 72.0.1 → 72.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/components/accordion/_macro.spec.js +2 -2
- package/components/address-input/_macro.spec.js +245 -322
- package/components/address-input/autosuggest.address.spec.js +16 -14
- package/components/address-output/_macro.spec.js +121 -74
- package/components/address-output/_test_examples.js +8 -0
- package/components/autosuggest/_macro.njk +1 -0
- package/components/autosuggest/_macro.spec.js +373 -178
- package/components/autosuggest/autosuggest.spec.js +3 -1
- package/components/autosuggest/autosuggest.ui.js +39 -10
- package/components/autosuggest/example-autosuggest-country.njk +2 -1
- package/components/autosuggest/fuse-config.js +7 -2
- package/components/back-to-top/back-to-top.dom.js +4 -4
- package/components/back-to-top/back-to-top.js +1 -1
- package/components/browser-banner/_macro.spec.js +11 -11
- package/components/button/_macro.njk +1 -1
- package/components/button/_macro.spec.js +405 -351
- package/components/button/example-button-group.njk +1 -0
- package/components/checkboxes/_checkbox-macro.njk +20 -0
- package/components/checkboxes/_checkbox.scss +3 -3
- package/components/checkboxes/_macro.njk +5 -0
- package/components/checkboxes/_macro.spec.js +35 -0
- package/components/checkboxes/example-checkboxes-with-revealed-text-area-expanded.njk +68 -0
- package/components/checkboxes/example-checkboxes-with-revealed-text-area.njk +67 -0
- package/components/details/_details.scss +1 -2
- package/components/details/example-details-open.njk +10 -0
- package/components/external-link/_macro.spec.js +66 -69
- package/components/external-link/_test_examples.js +4 -0
- package/components/feedback/_macro.spec.js +109 -80
- package/components/feedback/_test_examples.js +17 -0
- package/components/field/_macro.spec.js +106 -69
- package/components/section-navigation/_macro.njk +9 -6
- package/components/summary/_macro.njk +73 -78
- package/components/summary/_macro.spec.js +5 -15
- package/components/summary/_summary.scss +16 -11
- package/components/table-of-contents/_macro.njk +3 -3
- package/components/table-of-contents/_macro.spec.js +3 -3
- package/components/table-of-contents/{_toc.scss → _table-of-contents.scss} +1 -1
- package/components/table-of-contents/table-of-contents.dom.js +13 -0
- package/components/table-of-contents/{toc.js → table-of-contents.js} +4 -4
- package/components/table-of-contents/{toc.spec.js → table-of-contents.spec.js} +2 -2
- package/components/tabs/_tabs.scss +10 -11
- package/components/tabs/tabs.js +3 -3
- package/components/timeout-modal/timeout-modal.spec.js +1 -1
- package/css/main.css +1 -1
- package/js/analytics.js +1 -1
- package/js/main.js +1 -1
- package/package.json +2 -2
- package/scripts/main.es5.js +1 -1
- package/scripts/main.js +1 -1
- package/scss/main.scss +1 -1
- package/scss/objects/_page.scss +1 -1
- package/scss/utilities/_margin.scss +4 -0
- package/scss/utilities/_padding.scss +4 -0
- package/components/table-of-contents/toc.dom.js +0 -13
|
@@ -98,6 +98,26 @@
|
|
|
98
98
|
"radios": params.other.radios
|
|
99
99
|
})
|
|
100
100
|
}}
|
|
101
|
+
{% elif otherType == "textarea" %}
|
|
102
|
+
{% from "components/textarea/_macro.njk" import onsTextarea %}
|
|
103
|
+
{{
|
|
104
|
+
onsTextarea({
|
|
105
|
+
"id": params.other.id,
|
|
106
|
+
"name": params.other.name,
|
|
107
|
+
"value": params.other.value,
|
|
108
|
+
"label": {
|
|
109
|
+
"id": params.other.id + "-label",
|
|
110
|
+
"text": params.other.label.text,
|
|
111
|
+
"description": params.other.label.description,
|
|
112
|
+
"classes": 'ons-u-fw-n'
|
|
113
|
+
},
|
|
114
|
+
"charCheckLimit": {
|
|
115
|
+
"limit": params.other.charCheckLimit.limit,
|
|
116
|
+
"charCountSingular": params.other.charCheckLimit.charCountSingular,
|
|
117
|
+
"charCountPlural": params.other.charCheckLimit.charCountPlural
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
}}
|
|
101
121
|
{% endif %}
|
|
102
122
|
</span>
|
|
103
123
|
{% endif %}
|
|
@@ -107,7 +107,7 @@ $checkbox-padding: 10px;
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
.ons-checkbox__other {
|
|
110
|
-
margin: 0.5rem 0 0.5rem 0.
|
|
110
|
+
margin: 0.5rem 0 0.5rem 0.625rem;
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
|
|
@@ -170,8 +170,8 @@ $checkbox-padding: 10px;
|
|
|
170
170
|
&__other {
|
|
171
171
|
border-left: 4px solid var(--ons-color-borders-indent);
|
|
172
172
|
display: block;
|
|
173
|
-
margin: 0
|
|
174
|
-
padding: 0 $checkbox-padding $checkbox-padding $checkbox-padding * 2
|
|
173
|
+
margin: 0 1.1875rem 0.5rem;
|
|
174
|
+
padding: 0 $checkbox-padding $checkbox-padding $checkbox-padding * 2;
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
&__input:checked + &__label::before {
|
|
@@ -90,6 +90,11 @@
|
|
|
90
90
|
"label": {
|
|
91
91
|
"text": checkbox.other.label.text
|
|
92
92
|
},
|
|
93
|
+
"charCheckLimit": {
|
|
94
|
+
"limit": checkbox.other.charCheckLimit.limit,
|
|
95
|
+
"charCountSingular": checkbox.other.charCheckLimit.charCountSingular,
|
|
96
|
+
"charCountPlural": checkbox.other.charCheckLimit.charCountPlural
|
|
97
|
+
},
|
|
93
98
|
"legend": checkbox.other.legend,
|
|
94
99
|
"legendClasses": checkbox.other.legendClasses,
|
|
95
100
|
"value": checkbox.other.value,
|
|
@@ -87,6 +87,31 @@ const EXAMPLE_CHECKBOXES_WITH_MUTUALLY_EXCLUSIVE_WITH_ERROR = {
|
|
|
87
87
|
},
|
|
88
88
|
};
|
|
89
89
|
|
|
90
|
+
const EXAMPLE_CHECKBOX_ITEM_CHECKBOXES_WITH_TEXTAREA = {
|
|
91
|
+
name: 'example-checkboxes-name',
|
|
92
|
+
legend: 'Legend text',
|
|
93
|
+
checkboxesLabel: 'Select all that apply',
|
|
94
|
+
checkboxesLabelClasses: 'extra-checkboxes-label-class',
|
|
95
|
+
checkboxes: [
|
|
96
|
+
EXAMPLE_CHECKBOX_ITEM,
|
|
97
|
+
{
|
|
98
|
+
other: {
|
|
99
|
+
otherType: 'textarea',
|
|
100
|
+
id: 'other-textbox-example-checkbox-with-revealed-text-area',
|
|
101
|
+
name: 'other answer',
|
|
102
|
+
label: {
|
|
103
|
+
text: 'Provide more details',
|
|
104
|
+
},
|
|
105
|
+
charCheckLimit: {
|
|
106
|
+
limit: 300,
|
|
107
|
+
charCountSingular: 'You have {x} character remaining',
|
|
108
|
+
charCountPlural: 'You have {x} characters remaining',
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
};
|
|
114
|
+
|
|
90
115
|
describe('macro: checkboxes', () => {
|
|
91
116
|
it('passes jest-axe checks', async () => {
|
|
92
117
|
const $ = cheerio.load(renderComponent('checkboxes', EXAMPLE_CHECKBOXES));
|
|
@@ -135,6 +160,16 @@ describe('macro: checkboxes', () => {
|
|
|
135
160
|
});
|
|
136
161
|
});
|
|
137
162
|
|
|
163
|
+
describe('checkbox item with text area', () => {
|
|
164
|
+
it('renders the text area with expected parameters', () => {
|
|
165
|
+
const $ = cheerio.load(renderComponent('checkboxes', EXAMPLE_CHECKBOX_ITEM_CHECKBOXES_WITH_TEXTAREA));
|
|
166
|
+
expect($('.ons-input--textarea').attr('name')).toBe('other answer');
|
|
167
|
+
expect($('.ons-input--textarea').attr('maxlength')).toBe('300');
|
|
168
|
+
expect($('.ons-input__limit').attr('data-charcount-singular')).toBe('You have {x} character remaining');
|
|
169
|
+
expect($('.ons-input__limit').attr('data-charcount-plural')).toBe('You have {x} characters remaining');
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
138
173
|
describe('mutually exclusive', () => {
|
|
139
174
|
it('has the `ons-js-exclusive-group-item` class', () => {
|
|
140
175
|
const $ = cheerio.load(renderComponent('checkboxes', EXAMPLE_CHECKBOXES_WITH_MUTUALLY_EXCLUSIVE_WITH_ERROR));
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{% from "components/question/_macro.njk" import onsQuestion %}
|
|
2
|
+
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
|
|
3
|
+
|
|
4
|
+
{%
|
|
5
|
+
call onsQuestion({
|
|
6
|
+
"title": "Do you have any dietary requirements?",
|
|
7
|
+
"legendIsQuestionTitle": true,
|
|
8
|
+
"classes": "ons-u-mt-no"
|
|
9
|
+
})
|
|
10
|
+
%}
|
|
11
|
+
{{
|
|
12
|
+
onsCheckboxes({
|
|
13
|
+
"checkboxesLabel": "Select all that apply",
|
|
14
|
+
"dontWrap": true,
|
|
15
|
+
"checkboxes": [
|
|
16
|
+
{
|
|
17
|
+
"id": "gluten-free-example-checkbox-with-revealed-text-area",
|
|
18
|
+
"label": {
|
|
19
|
+
"text": "Gluten free"
|
|
20
|
+
},
|
|
21
|
+
"value": "gluten-free"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "lactose-intolerant-example-checkbox-with-revealed-text-area",
|
|
25
|
+
"label": {
|
|
26
|
+
"text": "Lactose intolerant"
|
|
27
|
+
},
|
|
28
|
+
"value": "lactose-intolerant"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "vegan-example-checkbox-with-revealed-text-area",
|
|
32
|
+
"label": {
|
|
33
|
+
"text": "Vegan"
|
|
34
|
+
},
|
|
35
|
+
"value": "vegan"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"id": "vegetarian-example-checkbox-with-revealed-text-area",
|
|
39
|
+
"label": {
|
|
40
|
+
"text": "Vegetarian"
|
|
41
|
+
},
|
|
42
|
+
"value": "vegetarian"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "other-checkbox-with-revealed-text-area",
|
|
46
|
+
"label": {
|
|
47
|
+
"text": "Other"
|
|
48
|
+
},
|
|
49
|
+
"value": "other",
|
|
50
|
+
"checked": true,
|
|
51
|
+
"other": {
|
|
52
|
+
"otherType": "textarea",
|
|
53
|
+
"id": "other-textbox-example-checkbox-with-revealed-text-area",
|
|
54
|
+
"name": "other-answer",
|
|
55
|
+
"label": {
|
|
56
|
+
"text": "Provide more details"
|
|
57
|
+
},
|
|
58
|
+
"charCheckLimit": {
|
|
59
|
+
"limit": 200,
|
|
60
|
+
"charCountSingular": "You have {x} character remaining",
|
|
61
|
+
"charCountPlural": "You have {x} characters remaining"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
})
|
|
67
|
+
}}
|
|
68
|
+
{% endcall %}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{% from "components/question/_macro.njk" import onsQuestion %}
|
|
2
|
+
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}
|
|
3
|
+
|
|
4
|
+
{%
|
|
5
|
+
call onsQuestion({
|
|
6
|
+
"title": "Do you have any dietary requirements?",
|
|
7
|
+
"legendIsQuestionTitle": true,
|
|
8
|
+
"classes": "ons-u-mt-no"
|
|
9
|
+
})
|
|
10
|
+
%}
|
|
11
|
+
{{
|
|
12
|
+
onsCheckboxes({
|
|
13
|
+
"checkboxesLabel": "Select all that apply",
|
|
14
|
+
"dontWrap": true,
|
|
15
|
+
"checkboxes": [
|
|
16
|
+
{
|
|
17
|
+
"id": "gluten-free-example-checkbox-with-revealed-text-area",
|
|
18
|
+
"label": {
|
|
19
|
+
"text": "Gluten free"
|
|
20
|
+
},
|
|
21
|
+
"value": "gluten-free"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "lactose-intolerant-example-checkbox-with-revealed-text-area",
|
|
25
|
+
"label": {
|
|
26
|
+
"text": "Lactose intolerant"
|
|
27
|
+
},
|
|
28
|
+
"value": "lactose-intolerant"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "vegan-example-checkbox-with-revealed-text-area",
|
|
32
|
+
"label": {
|
|
33
|
+
"text": "Vegan"
|
|
34
|
+
},
|
|
35
|
+
"value": "vegan"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"id": "vegetarian-example-checkbox-with-revealed-text-area",
|
|
39
|
+
"label": {
|
|
40
|
+
"text": "Vegetarian"
|
|
41
|
+
},
|
|
42
|
+
"value": "vegetarian"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "other-checkbox-with-revealed-text-area",
|
|
46
|
+
"label": {
|
|
47
|
+
"text": "Other"
|
|
48
|
+
},
|
|
49
|
+
"value": "other",
|
|
50
|
+
"other": {
|
|
51
|
+
"otherType": "textarea",
|
|
52
|
+
"id": "other-textbox-example-checkbox-with-revealed-text-area",
|
|
53
|
+
"name": "other-answer",
|
|
54
|
+
"label": {
|
|
55
|
+
"text": "Provide more details"
|
|
56
|
+
},
|
|
57
|
+
"charCheckLimit": {
|
|
58
|
+
"limit": 200,
|
|
59
|
+
"charCountSingular": "You have {x} character remaining",
|
|
60
|
+
"charCountPlural": "You have {x} characters remaining"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
})
|
|
66
|
+
}}
|
|
67
|
+
{% endcall %}
|
|
@@ -68,7 +68,6 @@ $details-caret-width: 1.75rem;
|
|
|
68
68
|
|
|
69
69
|
&--open & {
|
|
70
70
|
&__icon {
|
|
71
|
-
left: -0.1rem;
|
|
72
71
|
top: 0.2rem;
|
|
73
72
|
transform: rotate(90deg);
|
|
74
73
|
}
|
|
@@ -76,7 +75,7 @@ $details-caret-width: 1.75rem;
|
|
|
76
75
|
&__content {
|
|
77
76
|
border-left: 4px solid var(--ons-color-borders-indent);
|
|
78
77
|
display: block;
|
|
79
|
-
margin: 1rem 0 0;
|
|
78
|
+
margin: 1rem 0 0 0.5rem;
|
|
80
79
|
padding: 0 0 0 1.5rem;
|
|
81
80
|
}
|
|
82
81
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{% from "components/details/_macro.njk" import onsDetails %}
|
|
2
|
+
|
|
3
|
+
{{
|
|
4
|
+
onsDetails({
|
|
5
|
+
"id": "details-example",
|
|
6
|
+
"title": "What is a photovoltaic system?",
|
|
7
|
+
"content": "<p>A typical photovoltaic system employs solar panels, each comprising a number of solar cells, which generate electrical power. PV installations may be ground-mounted, rooftop mounted or wall mounted. The mount may be fixed, or use a solar tracker to follow the sun across the sky.</p>",
|
|
8
|
+
"open": true
|
|
9
|
+
})
|
|
10
|
+
}}
|
|
@@ -4,79 +4,76 @@ import * as cheerio from 'cheerio';
|
|
|
4
4
|
|
|
5
5
|
import axe from '../../tests/helpers/axe';
|
|
6
6
|
import { renderComponent, templateFaker } from '../../tests/helpers/rendering';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const $ = cheerio.load(renderComponent('external-link', EXAMPLE_EXTERNAL_LINK));
|
|
42
|
-
|
|
43
|
-
expect($('a').attr('target')).toBe('_blank');
|
|
44
|
-
expect($('a').attr('rel')).toBe('noopener');
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('has the expected link text', async () => {
|
|
48
|
-
const $ = cheerio.load(renderComponent('external-link', EXAMPLE_EXTERNAL_LINK));
|
|
49
|
-
|
|
50
|
-
const $hyperlink = $('a.ons-external-link .ons-external-link__text');
|
|
51
|
-
expect($hyperlink.text().trim()).toBe('Example link');
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('has a default new window description', async () => {
|
|
55
|
-
const $ = cheerio.load(renderComponent('external-link', EXAMPLE_EXTERNAL_LINK));
|
|
56
|
-
|
|
57
|
-
expect($('.ons-external-link__new-window-description').text()).toBe('(opens in a new tab)');
|
|
7
|
+
import { EXAMPLE_EXTERNAL_LINK } from './_test_examples';
|
|
8
|
+
|
|
9
|
+
describe('FOR: Macro: External-link', () => {
|
|
10
|
+
describe('GIVEN: Params: required', () => {
|
|
11
|
+
describe('WHEN: all required params are provided', () => {
|
|
12
|
+
const $ = cheerio.load(renderComponent('external-link', EXAMPLE_EXTERNAL_LINK));
|
|
13
|
+
test('THEN: jest-axe checks pass', async () => {
|
|
14
|
+
const results = await axe($.html());
|
|
15
|
+
expect(results).toHaveNoViolations();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('THEN: the link points to the expected URL', async () => {
|
|
19
|
+
const $hyperlink = $('a.ons-external-link');
|
|
20
|
+
expect($hyperlink.attr('href')).toBe('http://example.com');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('THEN: the link has the expected link text', async () => {
|
|
24
|
+
const $hyperlink = $('a.ons-external-link .ons-external-link__text');
|
|
25
|
+
expect($hyperlink.text().trim()).toBe('Example link');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('THEN: the link has a default new window description', async () => {
|
|
29
|
+
expect($('.ons-external-link__new-window-description').text()).toBe('(opens in a new tab)');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('THEN: the link has the external-link icon', async () => {
|
|
33
|
+
const faker = templateFaker();
|
|
34
|
+
const iconsSpy = faker.spy('icon');
|
|
35
|
+
faker.renderComponent('external-link', {
|
|
36
|
+
...EXAMPLE_EXTERNAL_LINK,
|
|
37
|
+
});
|
|
38
|
+
expect(iconsSpy.occurrences[0].iconType).toBe('external-link');
|
|
39
|
+
});
|
|
40
|
+
});
|
|
58
41
|
});
|
|
59
42
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
43
|
+
describe('GIVEN: Params: classes', () => {
|
|
44
|
+
describe('WHEN: additional style classes are provided with the classes param', () => {
|
|
45
|
+
const $ = cheerio.load(
|
|
46
|
+
renderComponent('external-link', {
|
|
47
|
+
...EXAMPLE_EXTERNAL_LINK,
|
|
48
|
+
classes: 'extra-class another-extra-class',
|
|
49
|
+
}),
|
|
50
|
+
);
|
|
51
|
+
test('THEN: renders with provided classes', () => {
|
|
52
|
+
expect($('.ons-external-link').hasClass('extra-class')).toBe(true);
|
|
53
|
+
expect($('.ons-external-link').hasClass('another-extra-class')).toBe(true);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
69
56
|
});
|
|
70
57
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
58
|
+
describe('GIVEN: Params: newWindowDescription', () => {
|
|
59
|
+
describe('WHEN: newWindowDescription param is provided', () => {
|
|
60
|
+
const $ = cheerio.load(
|
|
61
|
+
renderComponent('external-link', {
|
|
62
|
+
...EXAMPLE_EXTERNAL_LINK,
|
|
63
|
+
newWindowDescription: 'custom opens in a new tab text',
|
|
64
|
+
}),
|
|
65
|
+
);
|
|
66
|
+
test('THEN: has the expected new window description', () => {
|
|
67
|
+
expect($('.ons-external-link__new-window-description').text()).toBe('(custom opens in a new tab text)');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('THEN: the target attribute is set to _blank so that the link opens in a new window', () => {
|
|
71
|
+
expect($('a').attr('target')).toBe('_blank');
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('THEN: the rel attribute is set to noopener', () => {
|
|
75
|
+
expect($('a').attr('rel')).toBe('noopener');
|
|
76
|
+
});
|
|
78
77
|
});
|
|
79
|
-
|
|
80
|
-
expect(iconsSpy.occurrences[0].iconType).toBe('external-link');
|
|
81
78
|
});
|
|
82
79
|
});
|