@ons/design-system 53.1.1 → 54.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.
- package/components/accordion/_macro.njk +2 -3
- package/components/accordion/_macro.spec.js +3 -40
- package/components/accordion/accordion.dom.js +19 -0
- package/components/{collapsible/collapsible.group.js → accordion/accordion.js} +12 -5
- package/components/accordion/accordion.spec.js +56 -51
- package/components/collapsible/_collapsible.scss +58 -85
- package/components/collapsible/_macro.njk +6 -39
- package/components/collapsible/_macro.spec.js +0 -53
- package/components/collapsible/collapsible.dom.js +3 -12
- package/components/collapsible/collapsible.js +3 -45
- package/components/collapsible/collapsible.spec.js +6 -139
- package/components/cookies-banner/_cookies-banner.scss +15 -7
- package/components/cookies-banner/_macro.njk +66 -22
- package/components/cookies-banner/_macro.spec.js +172 -114
- package/components/cookies-banner/cookies-banner.js +35 -13
- package/components/cookies-banner/cookies-banner.spec.js +58 -54
- package/components/input/_macro.njk +20 -15
- package/components/input/_macro.spec.js +56 -0
- package/components/mutually-exclusive/mutually-exclusive.duration.spec.js +2 -0
- package/components/mutually-exclusive/mutually-exclusive.number.spec.js +1 -0
- package/css/census.css +1 -1
- package/css/ids.css +1 -1
- package/css/main.css +1 -1
- package/js/main.js +1 -0
- package/package.json +1 -1
- package/scripts/main.es5.js +1 -1
- package/scripts/main.js +2 -2
- package/scss/objects/_page.scss +1 -1
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
onsButton({
|
|
16
16
|
"type": "button",
|
|
17
17
|
"text": params.allButton.open,
|
|
18
|
-
"classes": "ons-js-
|
|
18
|
+
"classes": "ons-js-accordion-all ons-u-mb-s ons-u-d-no",
|
|
19
19
|
"variants": ["secondary", "small"],
|
|
20
|
-
"innerClasses": "ons-js-
|
|
20
|
+
"innerClasses": "ons-js-accordion-all-inner",
|
|
21
21
|
"attributes": attributes
|
|
22
22
|
})
|
|
23
23
|
}}
|
|
@@ -36,7 +36,6 @@
|
|
|
36
36
|
"content": item.content,
|
|
37
37
|
"group": params.id,
|
|
38
38
|
"saveState": params.saveState,
|
|
39
|
-
"variants": params.variants,
|
|
40
39
|
"open": params.open
|
|
41
40
|
})
|
|
42
41
|
}}
|
|
@@ -54,18 +54,6 @@ describe('macro: accordion', () => {
|
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
describe('item', () => {
|
|
57
|
-
it('has provided variant style classes', () => {
|
|
58
|
-
const $ = cheerio.load(
|
|
59
|
-
renderComponent('accordion', {
|
|
60
|
-
...EXAMPLE_ACCORDION_WITH_TWO_ITEMS,
|
|
61
|
-
variants: ['variant-a', 'variant-b'],
|
|
62
|
-
}),
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
expect($('.ons-collapsible--variant-a').length).toBe(2);
|
|
66
|
-
expect($('.ons-collapsible--variant-b').length).toBe(2);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
57
|
it('has provided title text', () => {
|
|
70
58
|
const $ = cheerio.load(renderComponent('accordion', EXAMPLE_ACCORDION_WITH_TWO_ITEMS));
|
|
71
59
|
|
|
@@ -103,31 +91,6 @@ describe('macro: accordion', () => {
|
|
|
103
91
|
expect(titleText).toBe('Content for item 1');
|
|
104
92
|
});
|
|
105
93
|
|
|
106
|
-
it('outputs a button with the expected class', () => {
|
|
107
|
-
const $ = cheerio.load(
|
|
108
|
-
renderComponent('accordion', {
|
|
109
|
-
itemsList: [
|
|
110
|
-
{
|
|
111
|
-
title: 'Title for item 1',
|
|
112
|
-
button: {
|
|
113
|
-
open: 'Open label',
|
|
114
|
-
close: 'Close label',
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
title: 'Title for item 2',
|
|
119
|
-
button: {
|
|
120
|
-
open: 'Open label',
|
|
121
|
-
close: 'Close label',
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
],
|
|
125
|
-
}),
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
expect($('button.ons-js-collapsible-button').length).toBe(2);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
94
|
it('has additionally provided `attributes`', () => {
|
|
132
95
|
const $ = cheerio.load(
|
|
133
96
|
renderComponent('accordion', {
|
|
@@ -199,7 +162,7 @@ describe('macro: accordion', () => {
|
|
|
199
162
|
}),
|
|
200
163
|
);
|
|
201
164
|
|
|
202
|
-
expect($('button.ons-js-
|
|
165
|
+
expect($('button.ons-js-accordion-all').length).toBe(1);
|
|
203
166
|
});
|
|
204
167
|
|
|
205
168
|
it('has additionally provided `attributes`', () => {
|
|
@@ -217,8 +180,8 @@ describe('macro: accordion', () => {
|
|
|
217
180
|
}),
|
|
218
181
|
);
|
|
219
182
|
|
|
220
|
-
expect($('button.ons-js-
|
|
221
|
-
expect($('button.ons-js-
|
|
183
|
+
expect($('button.ons-js-accordion-all').attr('a')).toBe('123');
|
|
184
|
+
expect($('button.ons-js-accordion-all').attr('b')).toBe('456');
|
|
222
185
|
});
|
|
223
186
|
});
|
|
224
187
|
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import domready from '../../js/domready';
|
|
2
|
+
|
|
3
|
+
async function initialiseAccordions() {
|
|
4
|
+
const toggleAllButtons = [...document.querySelectorAll('.ons-js-accordion-all')];
|
|
5
|
+
|
|
6
|
+
if (toggleAllButtons.length) {
|
|
7
|
+
const collapsibleComponents = [...document.querySelectorAll('.ons-js-collapsible')];
|
|
8
|
+
|
|
9
|
+
const Collapsible = (await import('../collapsible/collapsible')).default;
|
|
10
|
+
const Accordion = (await import('./accordion')).default;
|
|
11
|
+
const collapsibles = collapsibleComponents.map(element => new Collapsible(element));
|
|
12
|
+
|
|
13
|
+
toggleAllButtons.forEach(button => {
|
|
14
|
+
new Accordion(button, collapsibles);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
domready(initialiseAccordions);
|
|
@@ -1,23 +1,28 @@
|
|
|
1
|
-
export default class
|
|
1
|
+
export default class Accordion {
|
|
2
2
|
constructor(button, collapsibles) {
|
|
3
3
|
this.openCollapsibles = 0;
|
|
4
4
|
|
|
5
5
|
this.button = button;
|
|
6
|
-
this.buttonInner = button.querySelector('.ons-js-
|
|
6
|
+
this.buttonInner = button.querySelector('.ons-js-accordion-all-inner');
|
|
7
7
|
this.group = button.getAttribute('data-group');
|
|
8
8
|
this.collapsibles = collapsibles.filter(collapsible => collapsible.group === this.group);
|
|
9
|
-
|
|
10
9
|
this.totalCollapsibles = this.collapsibles.length;
|
|
11
|
-
this.
|
|
10
|
+
this.buttonOpenEl = this.buttonInner.querySelector('.ons-btn__text');
|
|
11
|
+
this.buttonOpen = this.buttonOpenEl.innerHTML.trim();
|
|
12
12
|
this.closeButton = button.getAttribute('data-close-all');
|
|
13
|
+
this.open = this.collapsibles.find(collapsible => collapsible.open === true);
|
|
13
14
|
|
|
14
15
|
this.collapsibles.forEach(collapsible => {
|
|
15
16
|
collapsible.onOpen = this.onOpen.bind(this);
|
|
16
17
|
collapsible.onClose = this.onClose.bind(this);
|
|
17
18
|
});
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
if (this.open) {
|
|
21
|
+
this.openCollapsibles = this.totalCollapsibles;
|
|
22
|
+
}
|
|
20
23
|
|
|
24
|
+
this.button.addEventListener('click', this.handleButtonClick.bind(this));
|
|
25
|
+
this.setButton();
|
|
21
26
|
this.button.classList.remove('ons-u-d-no');
|
|
22
27
|
}
|
|
23
28
|
|
|
@@ -49,9 +54,11 @@ export default class CollapsibleGroup {
|
|
|
49
54
|
if (this.canClose()) {
|
|
50
55
|
this.buttonInner.innerHTML = this.closeButton;
|
|
51
56
|
this.button.setAttribute('data-ga-label', this.buttonOpen);
|
|
57
|
+
this.button.setAttribute('aria-expanded', 'true');
|
|
52
58
|
} else {
|
|
53
59
|
this.buttonInner.innerHTML = this.buttonOpen;
|
|
54
60
|
this.button.setAttribute('data-ga-label', this.closeButton);
|
|
61
|
+
this.button.setAttribute('aria-expanded', 'false');
|
|
55
62
|
}
|
|
56
63
|
}
|
|
57
64
|
}
|
|
@@ -6,26 +6,14 @@ const EXAMPLE_ACCORDION_WITH_THREE_ITEMS = {
|
|
|
6
6
|
{
|
|
7
7
|
title: 'Title for item 1',
|
|
8
8
|
content: 'Content for item 1',
|
|
9
|
-
button: {
|
|
10
|
-
open: 'Open item',
|
|
11
|
-
close: 'Close item',
|
|
12
|
-
},
|
|
13
9
|
},
|
|
14
10
|
{
|
|
15
11
|
title: 'Title for item 2',
|
|
16
12
|
content: 'Content for item 2',
|
|
17
|
-
button: {
|
|
18
|
-
open: 'Open item',
|
|
19
|
-
close: 'Close item',
|
|
20
|
-
},
|
|
21
13
|
},
|
|
22
14
|
{
|
|
23
15
|
title: 'Title for item 3',
|
|
24
16
|
content: 'Content for item 3',
|
|
25
|
-
button: {
|
|
26
|
-
open: 'Open item',
|
|
27
|
-
close: 'Close item',
|
|
28
|
-
},
|
|
29
17
|
},
|
|
30
18
|
],
|
|
31
19
|
};
|
|
@@ -42,43 +30,68 @@ const EXAMPLE_ACCORDION_WITH_ALL_BUTTON = {
|
|
|
42
30
|
};
|
|
43
31
|
|
|
44
32
|
describe('script: accordion', () => {
|
|
45
|
-
it('begins with all items
|
|
46
|
-
await setTestPage(
|
|
33
|
+
it('begins with all items open when specified', async () => {
|
|
34
|
+
await setTestPage(
|
|
35
|
+
'/test',
|
|
36
|
+
renderComponent('accordion', {
|
|
37
|
+
...EXAMPLE_ACCORDION_WITH_THREE_ITEMS,
|
|
38
|
+
open: true,
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
47
41
|
|
|
48
|
-
const
|
|
49
|
-
expect(
|
|
42
|
+
const openElements = await page.$$eval('.ons-js-collapsible', nodes => nodes.filter(node => node.open));
|
|
43
|
+
expect(openElements[0]).not.toBe(undefined);
|
|
44
|
+
expect(openElements[1]).not.toBe(undefined);
|
|
45
|
+
expect(openElements[2]).not.toBe(undefined);
|
|
50
46
|
});
|
|
51
47
|
|
|
52
|
-
it('
|
|
48
|
+
it('sets toggle all button label to "Hide all" when open is specified', async () => {
|
|
53
49
|
await setTestPage(
|
|
54
50
|
'/test',
|
|
55
51
|
renderComponent('accordion', {
|
|
56
|
-
...
|
|
52
|
+
...EXAMPLE_ACCORDION_WITH_ALL_BUTTON,
|
|
53
|
+
open: true,
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const buttonText = await page.$eval('button[data-test-trigger]', element => element.innerText);
|
|
58
|
+
expect(buttonText.trim()).toBe('Close all');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('sets toggle all button aria-expanded set to true when open is specified', async () => {
|
|
62
|
+
await setTestPage(
|
|
63
|
+
'/test',
|
|
64
|
+
renderComponent('accordion', {
|
|
65
|
+
...EXAMPLE_ACCORDION_WITH_ALL_BUTTON,
|
|
57
66
|
open: true,
|
|
58
67
|
}),
|
|
59
68
|
);
|
|
60
69
|
|
|
61
|
-
const
|
|
62
|
-
expect(
|
|
70
|
+
const ariaExpanded = await page.$eval('button[data-test-trigger]', element => element.getAttribute('aria-expanded'));
|
|
71
|
+
expect(ariaExpanded).toBe('true');
|
|
63
72
|
});
|
|
64
73
|
|
|
65
|
-
it('opens all items when accordion
|
|
74
|
+
it('opens all items when accordion `allbutton` is clicked', async () => {
|
|
66
75
|
await setTestPage('/test', renderComponent('accordion', EXAMPLE_ACCORDION_WITH_ALL_BUTTON));
|
|
67
76
|
|
|
68
77
|
await page.click('button[data-test-trigger]');
|
|
69
78
|
|
|
70
|
-
const
|
|
71
|
-
expect(
|
|
79
|
+
const openElements = await page.$$eval('.ons-js-collapsible', nodes => nodes.filter(node => node.open));
|
|
80
|
+
expect(openElements[0]).not.toBe(undefined);
|
|
81
|
+
expect(openElements[1]).not.toBe(undefined);
|
|
82
|
+
expect(openElements[2]).not.toBe(undefined);
|
|
72
83
|
});
|
|
73
84
|
|
|
74
|
-
it('closes all items when accordion
|
|
85
|
+
it('closes all items when accordion `allbutton` is clicked twice', async () => {
|
|
75
86
|
await setTestPage('/test', renderComponent('accordion', EXAMPLE_ACCORDION_WITH_ALL_BUTTON));
|
|
76
87
|
|
|
77
88
|
await page.click('button[data-test-trigger]');
|
|
78
89
|
await page.click('button[data-test-trigger]');
|
|
79
90
|
|
|
80
|
-
const
|
|
81
|
-
expect(
|
|
91
|
+
const openElements = await page.$$eval('.ons-js-collapsible', nodes => nodes.filter(node => node.open));
|
|
92
|
+
expect(openElements[0]).toBe(undefined);
|
|
93
|
+
expect(openElements[1]).toBe(undefined);
|
|
94
|
+
expect(openElements[2]).toBe(undefined);
|
|
82
95
|
});
|
|
83
96
|
|
|
84
97
|
it('starts with the toggle all button labelled as "Open all"', async () => {
|
|
@@ -88,47 +101,39 @@ describe('script: accordion', () => {
|
|
|
88
101
|
expect(buttonText.trim()).toBe('Open all');
|
|
89
102
|
});
|
|
90
103
|
|
|
91
|
-
it('
|
|
104
|
+
it('starts with the toggle all button aria-expanded set to false', async () => {
|
|
92
105
|
await setTestPage('/test', renderComponent('accordion', EXAMPLE_ACCORDION_WITH_ALL_BUTTON));
|
|
93
106
|
|
|
94
|
-
await page
|
|
95
|
-
|
|
96
|
-
const buttonText = await page.$eval('button[data-test-trigger]', element => element.innerText);
|
|
97
|
-
expect(buttonText.trim()).toBe('Close all');
|
|
107
|
+
const ariaExpanded = await page.$eval('button[data-test-trigger]', element => element.getAttribute('aria-expanded'));
|
|
108
|
+
expect(ariaExpanded).toBe('false');
|
|
98
109
|
});
|
|
99
110
|
|
|
100
|
-
it('sets toggle all button label to "Hide all" when
|
|
111
|
+
it('sets toggle all button label to "Hide all" when clicked', async () => {
|
|
101
112
|
await setTestPage('/test', renderComponent('accordion', EXAMPLE_ACCORDION_WITH_ALL_BUTTON));
|
|
102
113
|
|
|
103
|
-
await page.click('
|
|
104
|
-
await page.click('#example-accordion-2 .ons-collapsible__btn');
|
|
105
|
-
await page.click('#example-accordion-3 .ons-collapsible__btn');
|
|
114
|
+
await page.click('button[data-test-trigger]');
|
|
106
115
|
|
|
107
116
|
const buttonText = await page.$eval('button[data-test-trigger]', element => element.innerText);
|
|
108
117
|
expect(buttonText.trim()).toBe('Close all');
|
|
109
118
|
});
|
|
110
119
|
|
|
111
|
-
it('
|
|
112
|
-
await setTestPage('/test', renderComponent('accordion',
|
|
120
|
+
it('sets toggle all button aria-expanded set to true when clicked', async () => {
|
|
121
|
+
await setTestPage('/test', renderComponent('accordion', EXAMPLE_ACCORDION_WITH_ALL_BUTTON));
|
|
113
122
|
|
|
114
|
-
await page.click('
|
|
115
|
-
await page.click('#example-accordion-3 .ons-collapsible__btn');
|
|
123
|
+
await page.click('button[data-test-trigger]');
|
|
116
124
|
|
|
117
|
-
const
|
|
118
|
-
expect(
|
|
125
|
+
const ariaExpanded = await page.$eval('button[data-test-trigger]', element => element.getAttribute('aria-expanded'));
|
|
126
|
+
expect(ariaExpanded).toBe('true');
|
|
119
127
|
});
|
|
120
128
|
|
|
121
|
-
it('
|
|
122
|
-
await setTestPage('/test', renderComponent('accordion',
|
|
123
|
-
|
|
124
|
-
await page.click('#example-accordion-2 .ons-collapsible__btn');
|
|
125
|
-
await page.click('#example-accordion-3 .ons-collapsible__btn');
|
|
126
|
-
await page.click('#example-accordion-3 .ons-collapsible__btn');
|
|
129
|
+
it('sets toggle all button label to "Hide all" when all items are shown', async () => {
|
|
130
|
+
await setTestPage('/test', renderComponent('accordion', EXAMPLE_ACCORDION_WITH_ALL_BUTTON));
|
|
127
131
|
|
|
128
|
-
|
|
129
|
-
|
|
132
|
+
await page.click('#example-accordion-1 .ons-collapsible__heading');
|
|
133
|
+
await page.click('#example-accordion-2 .ons-collapsible__heading');
|
|
134
|
+
await page.click('#example-accordion-3 .ons-collapsible__heading');
|
|
130
135
|
|
|
131
|
-
const
|
|
132
|
-
expect(
|
|
136
|
+
const buttonText = await page.$eval('button[data-test-trigger]', element => element.innerText);
|
|
137
|
+
expect(buttonText.trim()).toBe('Close all');
|
|
133
138
|
});
|
|
134
139
|
});
|
|
@@ -1,106 +1,81 @@
|
|
|
1
1
|
$collapsible-caret-width: 1.5rem;
|
|
2
2
|
|
|
3
3
|
.ons-collapsible {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
4
|
+
&__heading {
|
|
5
|
+
color: $color-text-link;
|
|
6
|
+
cursor: pointer;
|
|
7
|
+
display: inline-block;
|
|
8
|
+
outline: none;
|
|
9
|
+
padding: 0 0 0 $collapsible-caret-width;
|
|
10
|
+
pointer-events: initial;
|
|
11
|
+
position: relative;
|
|
12
|
+
|
|
13
|
+
&::marker {
|
|
14
|
+
display: none;
|
|
15
|
+
}
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
.ons-collapsible__icon .ons-svg-icon {
|
|
26
|
-
fill: $color-text-link-focus;
|
|
27
|
-
}
|
|
17
|
+
&:focus {
|
|
18
|
+
.ons-collapsible__title {
|
|
19
|
+
@extend %a-focus;
|
|
20
|
+
// extend collapsible focus background behind caret
|
|
21
|
+
margin-left: -$collapsible-caret-width;
|
|
22
|
+
padding-left: $collapsible-caret-width;
|
|
28
23
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
color: $color-text-link-hover;
|
|
32
|
-
.ons-collapsible__icon {
|
|
33
|
-
fill: $color-text-link-hover;
|
|
34
|
-
}
|
|
35
|
-
.ons-collapsible__title {
|
|
36
|
-
text-decoration: underline solid $color-text-link-hover 2px;
|
|
37
|
-
}
|
|
24
|
+
.ons-collapsible__icon .ons-svg-icon {
|
|
25
|
+
fill: $color-text-link-focus;
|
|
38
26
|
}
|
|
39
27
|
}
|
|
40
28
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
29
|
+
&:hover:not(:focus) {
|
|
30
|
+
color: $color-text-link-hover;
|
|
31
|
+
.ons-collapsible__icon {
|
|
32
|
+
fill: $color-text-link-hover;
|
|
33
|
+
}
|
|
34
|
+
.ons-collapsible__title {
|
|
35
|
+
text-decoration: underline solid $color-text-link-hover 2px;
|
|
36
|
+
}
|
|
49
37
|
}
|
|
38
|
+
}
|
|
50
39
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
40
|
+
&__icon {
|
|
41
|
+
display: inline-block;
|
|
42
|
+
fill: $color-text-link;
|
|
43
|
+
height: $collapsible-caret-width;
|
|
44
|
+
left: -0.15rem;
|
|
45
|
+
position: absolute;
|
|
46
|
+
top: -0.2rem;
|
|
47
|
+
width: $collapsible-caret-width;
|
|
48
|
+
}
|
|
59
49
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
50
|
+
&__title {
|
|
51
|
+
display: inline-block;
|
|
52
|
+
font-size: 1rem;
|
|
53
|
+
font-weight: $font-weight-bold;
|
|
54
|
+
margin-bottom: 0;
|
|
55
|
+
text-underline-position: under;
|
|
56
|
+
transform: translateY(-1px);
|
|
63
57
|
}
|
|
64
58
|
|
|
65
|
-
&
|
|
66
|
-
|
|
59
|
+
&__content {
|
|
60
|
+
border-left: 4px solid $color-borders-indent;
|
|
61
|
+
display: block;
|
|
62
|
+
margin: 1rem 0 0;
|
|
63
|
+
padding: 0 0 0 1.3em;
|
|
67
64
|
}
|
|
68
65
|
|
|
69
|
-
|
|
66
|
+
&[open] & {
|
|
70
67
|
&__icon {
|
|
71
68
|
left: -0.1rem;
|
|
72
|
-
top: 0.
|
|
69
|
+
top: 0.2rem;
|
|
73
70
|
transform: rotate(90deg);
|
|
74
71
|
}
|
|
75
|
-
|
|
76
|
-
&__content {
|
|
77
|
-
border-left: 4px solid $color-borders-indent;
|
|
78
|
-
display: block;
|
|
79
|
-
margin: 1rem 0 0;
|
|
80
|
-
padding: 0 0 0 1.3em;
|
|
81
|
-
|
|
82
|
-
.ons-btn {
|
|
83
|
-
margin-bottom: 0.5rem;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
&--accordion {
|
|
89
|
-
margin: 0;
|
|
90
|
-
&.ons-collapsible--open {
|
|
91
|
-
.ons-svg-icon {
|
|
92
|
-
left: 0.4rem;
|
|
93
|
-
position: absolute;
|
|
94
|
-
top: 0.25rem;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
72
|
}
|
|
98
73
|
|
|
99
74
|
&--accordion & {
|
|
100
75
|
&__heading {
|
|
101
76
|
border-top: 1px solid $color-borders;
|
|
102
77
|
margin: 0;
|
|
103
|
-
padding-bottom:
|
|
78
|
+
padding-bottom: 0.9rem;
|
|
104
79
|
padding-top: 1rem;
|
|
105
80
|
width: 100%;
|
|
106
81
|
|
|
@@ -115,10 +90,6 @@ $collapsible-caret-width: 1.5rem;
|
|
|
115
90
|
|
|
116
91
|
&__icon {
|
|
117
92
|
top: 0.8rem;
|
|
118
|
-
|
|
119
|
-
@include mq(s) {
|
|
120
|
-
top: 1.15rem;
|
|
121
|
-
}
|
|
122
93
|
}
|
|
123
94
|
|
|
124
95
|
&__controls {
|
|
@@ -138,10 +109,12 @@ $collapsible-caret-width: 1.5rem;
|
|
|
138
109
|
padding: 0;
|
|
139
110
|
}
|
|
140
111
|
}
|
|
112
|
+
}
|
|
141
113
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
114
|
+
.ons-collapsible--accordion {
|
|
115
|
+
&[open] {
|
|
116
|
+
.ons-collapsible__icon {
|
|
117
|
+
top: 1.2rem;
|
|
145
118
|
}
|
|
146
119
|
}
|
|
147
120
|
}
|
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
{% macro onsCollapsible(params) %}
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
<div
|
|
2
|
+
<details
|
|
5
3
|
id="{{ params.id }}"
|
|
6
|
-
class="ons-collapsible ons-js-collapsible{% if params.isAccordion is defined and params.isAccordion %} ons-collapsible--accordion{% endif %}{% if params.classes is defined and params.classes %} {{ params.classes }}{% endif %}
|
|
7
|
-
{% if params.button is defined and params.button and params.button.close is defined and params.button.close %} data-btn-close="{{ params.button.close }}"{% endif %}
|
|
4
|
+
class="ons-collapsible ons-js-collapsible{% if params.isAccordion is defined and params.isAccordion %} ons-collapsible--accordion{% endif %}{% if params.classes is defined and params.classes %} {{ params.classes }}{% endif %}"
|
|
8
5
|
{% if params.group is defined and params.group %} data-group="{{ params.group }}"{% endif %}
|
|
9
6
|
{% if params.attributes is defined and params.attributes %}{% for attribute, value in (params.attributes.items() if params.attributes is mapping and params.attributes.items else params.attributes) %}{{ attribute }}{% if value is defined and value %}="{{ value }}"{% endif %} {% endfor %}{% endif %}
|
|
10
7
|
{% if params.saveState is defined and params.saveState %} data-save-state="true"{% endif %}
|
|
11
8
|
{% if params.open is defined and params.open %} data-open="true"{% endif %}
|
|
12
9
|
>
|
|
13
|
-
<
|
|
10
|
+
<summary
|
|
14
11
|
class="ons-collapsible__heading ons-js-collapsible-heading"
|
|
15
12
|
{% if params.headingAttributes is defined and params.headingAttributes %}{% for attribute, value in (params.headingAttributes.items() if params.headingAttributes is mapping and params.headingAttributes.items else params.headingAttributes) %}{{ attribute }}{% if value is defined and value %}="{{ value }}"{% endif %} {% endfor %}{% endif %}
|
|
16
13
|
>
|
|
17
|
-
{# Required to use display flex on Safari as it's not currently supported: https://bugs.webkit.org/show_bug.cgi?id=167111 #}
|
|
18
|
-
<div class="ons-collapsible__controls">
|
|
19
14
|
{% set titleTag = params.titleTag | default("h2") %}
|
|
20
15
|
<{{ titleTag }} class="ons-collapsible__title">{{ params.title }}</{{ titleTag }}>
|
|
21
16
|
<span class="ons-collapsible__icon">
|
|
@@ -25,39 +20,11 @@
|
|
|
25
20
|
"iconType": "chevron"
|
|
26
21
|
})
|
|
27
22
|
}}</span>
|
|
28
|
-
|
|
29
|
-
{{
|
|
30
|
-
onsButton({
|
|
31
|
-
"type": "button",
|
|
32
|
-
"text": params.button.open,
|
|
33
|
-
"classes": "ons-collapsible__btn ons-js-collapsible-button ons-u-d-no ons-u-d-no@xxs@s",
|
|
34
|
-
"innerClasses": "ons-js-collapsible-button-inner",
|
|
35
|
-
"variants": ["secondary", "small"],
|
|
36
|
-
"attributes": params.button.attributes
|
|
37
|
-
})
|
|
38
|
-
}}
|
|
39
|
-
{% endif %}
|
|
40
|
-
</div>
|
|
41
|
-
</div>
|
|
23
|
+
</summary>
|
|
42
24
|
<div id="{{ params.id }}-content" class="ons-collapsible__content ons-js-collapsible-content"
|
|
43
25
|
{% if params.contentAttributes is defined and params.contentAttributes %}{% for attribute, value in (params.contentAttributes.items() if params.contentAttributes is mapping and params.contentAttributes.items else params.contentAttributes) %}{{ attribute }}{% if value is defined and value %}="{{ value }}"{% endif %} {% endfor %}{% endif %}
|
|
44
26
|
>
|
|
45
|
-
{
|
|
46
|
-
{{ params.content | safe }}{{ caller() if caller }}
|
|
47
|
-
{% else %}
|
|
48
|
-
{{ params.content | safe }}{{ caller() if caller }}
|
|
49
|
-
{{
|
|
50
|
-
onsButton({
|
|
51
|
-
"type": "button",
|
|
52
|
-
"text": params.button.close | default ('Hide this'),
|
|
53
|
-
"buttonContext": (params.button.context | default(params.title)) + " " + params.button.contextSuffix | default("content"),
|
|
54
|
-
"classes": "ons-js-collapsible-button ons-u-d-no " + (params.button.classes | default("ons-btn--secondary")),
|
|
55
|
-
"innerClasses": "ons-js-collapsible-button-inner",
|
|
56
|
-
"variants": "small",
|
|
57
|
-
"attributes": params.button.attributes
|
|
58
|
-
})
|
|
59
|
-
}}
|
|
60
|
-
{% endif %}
|
|
27
|
+
{{ params.content | safe }}{{ caller() if caller }}
|
|
61
28
|
</div>
|
|
62
|
-
</
|
|
29
|
+
</details>
|
|
63
30
|
{% endmacro %}
|
|
@@ -37,18 +37,6 @@ describe('macro: collapsible', () => {
|
|
|
37
37
|
expect($('.ons-collapsible').hasClass('another-extra-class')).toBe(true);
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
it('has provided variant style classes', () => {
|
|
41
|
-
const $ = cheerio.load(
|
|
42
|
-
renderComponent('collapsible', {
|
|
43
|
-
...EXAMPLE_COLLAPSIBLE_BASIC,
|
|
44
|
-
variants: ['variant-a', 'variant-b'],
|
|
45
|
-
}),
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
expect($('.ons-collapsible--variant-a').length).toBe(1);
|
|
49
|
-
expect($('.ons-collapsible--variant-b').length).toBe(1);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
40
|
it('has provided title text', () => {
|
|
53
41
|
const $ = cheerio.load(renderComponent('collapsible', EXAMPLE_COLLAPSIBLE_BASIC));
|
|
54
42
|
|
|
@@ -152,47 +140,6 @@ describe('macro: collapsible', () => {
|
|
|
152
140
|
expect(iconsSpy.occurrences[0].iconType).toBe('chevron');
|
|
153
141
|
});
|
|
154
142
|
|
|
155
|
-
it('has the expected button output', () => {
|
|
156
|
-
const faker = templateFaker();
|
|
157
|
-
const buttonSpy = faker.spy('button');
|
|
158
|
-
|
|
159
|
-
faker.renderComponent('collapsible', {
|
|
160
|
-
...EXAMPLE_COLLAPSIBLE_BASIC,
|
|
161
|
-
button: {
|
|
162
|
-
close: 'Close this',
|
|
163
|
-
attributes: {
|
|
164
|
-
a: 123,
|
|
165
|
-
b: 456,
|
|
166
|
-
},
|
|
167
|
-
},
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
expect(buttonSpy.occurrences[0]).toEqual({
|
|
171
|
-
text: 'Close this',
|
|
172
|
-
type: 'button',
|
|
173
|
-
buttonContext: 'Title for collapsible content',
|
|
174
|
-
classes: 'ons-js-collapsible-button ons-u-d-no ons-btn--secondary',
|
|
175
|
-
innerClasses: 'ons-js-collapsible-button-inner',
|
|
176
|
-
variants: 'small',
|
|
177
|
-
attributes: {
|
|
178
|
-
a: 123,
|
|
179
|
-
b: 456,
|
|
180
|
-
},
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
it('has the expected data attribute when `button` is provided', () => {
|
|
185
|
-
const $ = cheerio.load(
|
|
186
|
-
renderComponent('collapsible', {
|
|
187
|
-
...EXAMPLE_COLLAPSIBLE_BASIC,
|
|
188
|
-
button: {
|
|
189
|
-
close: 'Close this',
|
|
190
|
-
},
|
|
191
|
-
}),
|
|
192
|
-
);
|
|
193
|
-
expect($('.ons-collapsible').attr('data-btn-close')).toBe('Close this');
|
|
194
|
-
});
|
|
195
|
-
|
|
196
143
|
it('calls with content', () => {
|
|
197
144
|
const $ = cheerio.load(renderComponent('collapsible', { EXAMPLE_COLLAPSIBLE_BASIC }, 'Example content...'));
|
|
198
145
|
|