Skip to content

Commit 12ae2f7

Browse files
feat(collapse): accessibility support (#203)
feat(collapse): accessibility support style(collapse): use spacers chore(collapse): preload icon Co-authored-by: Sakchai Homhual <87511654+Sakchai-Refinitiv@users.noreply.github.com>
1 parent 5ae9d27 commit 12ae2f7

File tree

8 files changed

+288
-119
lines changed

8 files changed

+288
-119
lines changed

packages/elemental-theme/src/custom-elements/ef-collapse.less

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,30 @@
77
[part="toggle"] {
88
transition: @global-transition-duration @global-transition-easing;
99
opacity: .5;
10-
margin-right: 0.5em;
11-
margin-left: 0.8em;
10+
margin-right: 0.25em;
11+
margin-left: extract(@header-padding, 2);
1212
flex-shrink: 0;
13+
pointer-events: none;
1314
}
1415

1516
&[expanded] [part="toggle"] {
1617
transform: rotate(90deg);
1718
}
1819

19-
[part="header"] {
20+
[part~=header] {
21+
padding: 0;
22+
&[focused="visible"] {
23+
background-color: @button-hover-background-color;
24+
}
25+
}
26+
27+
[part="header-toggle"] {
2028
.touch-action();
29+
cursor: pointer;
30+
overflow: hidden;
31+
white-space: nowrap;
32+
text-overflow: ellipsis;
33+
outline: none;
2134
}
2235

2336
@keyframes expand {
@@ -60,7 +73,10 @@
6073
animation-name: expand;
6174
}
6275

63-
[part="content"] ef-panel:not([spacing]) {
64-
padding: var(--panel-padding);
76+
[part="content"] ef-panel {
77+
overflow: auto;
78+
&:not([spacing]) {
79+
padding: var(--panel-padding);
80+
}
6581
}
6682
}

packages/elements/src/accordion/__test__/accordion.test.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ describe('accordion/Accordion', () => {
3939
</ef-collapse>
4040
</ef-accordion>`);
4141
const items = el.querySelectorAll('ef-collapse');
42-
const header1 = items[0].shadowRoot.querySelector('[part=header]');
43-
const header2 = items[1].shadowRoot.querySelector('[part=header]');
42+
const header1 = items[0].shadowRoot.querySelector('[part=header-toggle]');
43+
const header2 = items[1].shadowRoot.querySelector('[part=header-toggle]');
4444

4545
setTimeout(() => header1.dispatchEvent(new Event('tap')));
4646
await oneEvent(header1, 'tap');
@@ -66,8 +66,8 @@ describe('accordion/Accordion', () => {
6666
</ef-collapse>
6767
</ef-accordion>`);
6868
const items = el.querySelectorAll('ef-collapse');
69-
const header1 = items[0].shadowRoot.querySelector('[part=header]');
70-
const header2 = items[1].shadowRoot.querySelector('[part=header]');
69+
const header1 = items[0].shadowRoot.querySelector('[part=header-toggle]');
70+
const header2 = items[1].shadowRoot.querySelector('[part=header-toggle]');
7171

7272
setTimeout(() => header1.dispatchEvent(new Event('tap')));
7373
await oneEvent(header1, 'tap');
@@ -105,7 +105,7 @@ describe('accordion/Accordion', () => {
105105
`);
106106
const topLevelCollapses = el.querySelectorAll('ef-collapse.top-level');
107107
const nestedCollapses = el.querySelectorAll('ef-collapse:not(.top-level)');
108-
const nestedHeader2 = nestedCollapses[1].shadowRoot.querySelector('[part=header]');
108+
const nestedHeader2 = nestedCollapses[1].shadowRoot.querySelector('[part=header-toggle]');
109109

110110
expect(topLevelCollapses[0].expanded).to.equal(true);
111111
expect(topLevelCollapses[1].expanded).to.equal(false);

packages/elements/src/collapse/__demo__/index.html

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,24 @@
1111
}
1212
.badge {
1313
border-radius: 100%;
14-
height: 21px;
15-
width: 21px;
14+
height: 19px;
15+
width: 19px;
1616
font-size: 12px;
1717
line-height: 18px;
18-
border: 2px solid currentColor;
18+
border: 1px solid currentColor;
1919
box-sizing: border-box;
2020
display: flex;
2121
justify-content: center;
22+
margin: auto 0;
23+
}
24+
.status {
25+
display: inline-flex;
26+
width: 3px;
27+
height: 100%;
28+
background-color: #2a9d54;
29+
}
30+
.status.red {
31+
background-color: #e31414;
2232
}
2333
.overflow {
2434
background: red;
@@ -29,7 +39,11 @@
2939
height: 200%;
3040
}
3141
.checkbox {
32-
margin-right: 5px;
42+
margin: auto 5px;
43+
}
44+
.menu {
45+
color: currentColor;
46+
margin: auto 0;
3347
}
3448
</style>
3549
</head>
@@ -42,8 +56,9 @@
4256
</script>
4357

4458
<demo-block header="Default" layout="normal">
45-
<ef-collapse header="Collapsible">
59+
<ef-collapse header="A long header that should truncate when there is not enough screen space">
4660
<div class="content">Content inside a div with a fixed 100px height</div>
61+
<ef-button>Cannot focus when collapsed</ef-button>
4762
</ef-collapse>
4863
</demo-block>
4964

@@ -81,11 +96,25 @@
8196
</demo-block>
8297

8398
<demo-block header="Use Slot" layout="normal" tags="slot">
84-
<ef-checkbox slot="header-left"></ef-checkbox>
8599
<ef-collapse header="Close above 14D SMA">
86100
<ef-checkbox slot="header-left" class="checkbox"></ef-checkbox>
87101
<div slot="header-right" class="badge">8</div>
88-
<ef-button slot="header-right" icon="menu" transparent></ef-button>
102+
<ef-button slot="header-right" icon="menu" class="menu" transparent></ef-button>
103+
<div class="status" slot="header-right"></div>
104+
<div class="content">Content inside a div with a fixed 100px height</div>
105+
</ef-collapse>
106+
<ef-collapse header="Close below 14D SMA">
107+
<ef-checkbox slot="header-left" class="checkbox"></ef-checkbox>
108+
<div slot="header-right" class="badge">8</div>
109+
<ef-button slot="header-right" icon="menu" class="menu" transparent></ef-button>
110+
<div class="status red" slot="header-right"></div>
111+
<div class="content">Content inside a div with a fixed 100px height</div>
112+
</ef-collapse>
113+
<ef-collapse header="New 52 week high">
114+
<ef-checkbox slot="header-left" class="checkbox"></ef-checkbox>
115+
<div slot="header-right" class="badge">8</div>
116+
<ef-button slot="header-right" icon="menu" class="menu" transparent></ef-button>
117+
<div class="status" slot="header-right"></div>
89118
<div class="content">Content inside a div with a fixed 100px height</div>
90119
</ef-collapse>
91120
</demo-block>

packages/elements/src/collapse/__snapshots__/Collapse.md

Lines changed: 126 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,22 @@
99
level="3"
1010
part="header"
1111
>
12+
<div
13+
part="heading"
14+
role="heading"
15+
>
16+
<div
17+
aria-controls="content"
18+
aria-expanded="false"
19+
id="header-toggle"
20+
part="header-toggle"
21+
role="button"
22+
tabindex="0"
23+
>
24+
</div>
25+
</div>
1226
<ef-icon
27+
aria-hidden="true"
1328
icon="right"
1429
part="toggle"
1530
slot="left"
@@ -26,8 +41,16 @@
2641
>
2742
</slot>
2843
</ef-header>
29-
<div part="content">
30-
<ef-panel transparent="">
44+
<div
45+
aria-labelledby="header-toggle"
46+
id="content"
47+
part="content"
48+
role="region"
49+
>
50+
<ef-panel
51+
part="content-data"
52+
transparent=""
53+
>
3154
<slot>
3255
</slot>
3356
</ef-panel>
@@ -42,7 +65,22 @@
4265
level="3"
4366
part="header"
4467
>
68+
<div
69+
part="heading"
70+
role="heading"
71+
>
72+
<div
73+
aria-controls="content"
74+
aria-expanded="false"
75+
id="header-toggle"
76+
part="header-toggle"
77+
role="button"
78+
tabindex="0"
79+
>
80+
</div>
81+
</div>
4582
<ef-icon
83+
aria-hidden="true"
4684
icon="right"
4785
part="toggle"
4886
slot="left"
@@ -59,8 +97,16 @@
5997
>
6098
</slot>
6199
</ef-header>
62-
<div part="content">
63-
<ef-panel transparent="">
100+
<div
101+
aria-labelledby="header-toggle"
102+
id="content"
103+
part="content"
104+
role="region"
105+
>
106+
<ef-panel
107+
part="content-data"
108+
transparent=""
109+
>
64110
<slot>
65111
</slot>
66112
</ef-panel>
@@ -75,7 +121,23 @@
75121
level="3"
76122
part="header"
77123
>
124+
<div
125+
part="heading"
126+
role="heading"
127+
>
128+
<div
129+
aria-controls="content"
130+
aria-expanded="false"
131+
id="header-toggle"
132+
part="header-toggle"
133+
role="button"
134+
tabindex="0"
135+
>
136+
Header
137+
</div>
138+
</div>
78139
<ef-icon
140+
aria-hidden="true"
79141
icon="right"
80142
part="toggle"
81143
slot="left"
@@ -91,10 +153,17 @@
91153
slot="right"
92154
>
93155
</slot>
94-
Header
95156
</ef-header>
96-
<div part="content">
97-
<ef-panel transparent="">
157+
<div
158+
aria-labelledby="header-toggle"
159+
id="content"
160+
part="content"
161+
role="region"
162+
>
163+
<ef-panel
164+
part="content-data"
165+
transparent=""
166+
>
98167
<slot>
99168
</slot>
100169
</ef-panel>
@@ -109,7 +178,22 @@
109178
level="1"
110179
part="header"
111180
>
181+
<div
182+
part="heading"
183+
role="heading"
184+
>
185+
<div
186+
aria-controls="content"
187+
aria-expanded="false"
188+
id="header-toggle"
189+
part="header-toggle"
190+
role="button"
191+
tabindex="0"
192+
>
193+
</div>
194+
</div>
112195
<ef-icon
196+
aria-hidden="true"
113197
icon="right"
114198
part="toggle"
115199
slot="left"
@@ -126,8 +210,16 @@
126210
>
127211
</slot>
128212
</ef-header>
129-
<div part="content">
130-
<ef-panel transparent="">
213+
<div
214+
aria-labelledby="header-toggle"
215+
id="content"
216+
part="content"
217+
role="region"
218+
>
219+
<ef-panel
220+
part="content-data"
221+
transparent=""
222+
>
131223
<slot>
132224
</slot>
133225
</ef-panel>
@@ -142,7 +234,22 @@
142234
level=""
143235
part="header"
144236
>
237+
<div
238+
part="heading"
239+
role="heading"
240+
>
241+
<div
242+
aria-controls="content"
243+
aria-expanded="false"
244+
id="header-toggle"
245+
part="header-toggle"
246+
role="button"
247+
tabindex="0"
248+
>
249+
</div>
250+
</div>
145251
<ef-icon
252+
aria-hidden="true"
146253
icon="right"
147254
part="toggle"
148255
slot="left"
@@ -159,8 +266,16 @@
159266
>
160267
</slot>
161268
</ef-header>
162-
<div part="content">
163-
<ef-panel transparent="">
269+
<div
270+
aria-labelledby="header-toggle"
271+
id="content"
272+
part="content"
273+
role="region"
274+
>
275+
<ef-panel
276+
part="content-data"
277+
transparent=""
278+
>
164279
<slot>
165280
</slot>
166281
</ef-panel>

0 commit comments

Comments
 (0)