Skip to content

Commit f35352c

Browse files
authored
[EuiAccordion] Fix accordion right arrow display when combined with extraAction (#3971)
1 parent 3f80fe9 commit f35352c

File tree

10 files changed

+97
-21
lines changed

10 files changed

+97
-21
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
**Bug fixes**
66

77
- Fix incorrect `euiCodeBlockNameColor` variable usage for `.hljs-name` in SCSS ([#3991](https://github.com/elastic/eui/pull/3991))
8+
- Fixed bug in `EuiAccordion` where the `arrowDisplay="right"` is ignored when `extraAction` is configured ([#3971](https://github.com/elastic/eui/pull/3971))
89

910
## [`28.3.1`](https://github.com/elastic/eui/tree/v28.3.1)
1011

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
11
import React from 'react';
22

3-
import { EuiAccordion, EuiButton } from '../../../../src/components';
3+
import { EuiAccordion, EuiButton, EuiSpacer } from '../../../../src/components';
44

55
export default () => (
6-
<EuiAccordion
7-
id="accordionExtra"
8-
buttonContent="Click to open"
9-
extraAction={<EuiButton size="s">Extra action!</EuiButton>}
10-
paddingSize="l">
11-
<div>Opened content.</div>
12-
</EuiAccordion>
6+
<>
7+
<EuiAccordion
8+
id="accordionExtraWithLeftArrow"
9+
buttonContent="Click to open (Arrow on the left)"
10+
extraAction={<EuiButton size="s">Extra action!</EuiButton>}
11+
paddingSize="l">
12+
<div>Opened content.</div>
13+
</EuiAccordion>
14+
15+
<EuiSpacer />
16+
17+
<EuiAccordion
18+
id="accordionExtraWithRightArrow"
19+
arrowDisplay="right"
20+
buttonContent="Click to open (Arrow on the right)"
21+
extraAction={<EuiButton size="s">Extra action!</EuiButton>}
22+
paddingSize="l">
23+
<div>Opened content.</div>
24+
</EuiAccordion>
25+
</>
1326
);

src/components/accordion/__snapshots__/accordion.test.tsx.snap

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ exports[`EuiAccordion behavior closes when clicked twice 1`] = `
1919
aria-controls="12"
2020
aria-expanded={false}
2121
className="euiAccordion__button"
22+
id="generated-id"
2223
onClick={[Function]}
2324
type="button"
2425
>
@@ -79,6 +80,7 @@ exports[`EuiAccordion behavior opens when clicked once 1`] = `
7980
aria-controls="11"
8081
aria-expanded={true}
8182
className="euiAccordion__button"
83+
id="generated-id"
8284
onClick={[Function]}
8385
type="button"
8486
>
@@ -133,6 +135,7 @@ exports[`EuiAccordion is rendered 1`] = `
133135
aria-controls="0"
134136
aria-expanded="false"
135137
class="euiAccordion__button"
138+
id="generated-id"
136139
type="button"
137140
>
138141
<span
@@ -172,6 +175,7 @@ exports[`EuiAccordion props arrowDisplay none is rendered 1`] = `
172175
aria-controls="6"
173176
aria-expanded="false"
174177
class="euiAccordion__button"
178+
id="generated-id"
175179
type="button"
176180
>
177181
<span
@@ -207,6 +211,7 @@ exports[`EuiAccordion props arrowDisplay right is rendered 1`] = `
207211
aria-controls="5"
208212
aria-expanded="false"
209213
class="euiAccordion__button euiAccordion__buttonReverse"
214+
id="generated-id"
210215
type="button"
211216
>
212217
<span
@@ -250,6 +255,7 @@ exports[`EuiAccordion props buttonContent is rendered 1`] = `
250255
aria-controls="2"
251256
aria-expanded="false"
252257
class="euiAccordion__button"
258+
id="generated-id"
253259
type="button"
254260
>
255261
<span
@@ -293,6 +299,7 @@ exports[`EuiAccordion props buttonContentClassName is rendered 1`] = `
293299
aria-controls="1"
294300
aria-expanded="false"
295301
class="euiAccordion__button"
302+
id="generated-id"
296303
type="button"
297304
>
298305
<span
@@ -332,6 +339,7 @@ exports[`EuiAccordion props extraAction is rendered 1`] = `
332339
aria-controls="3"
333340
aria-expanded="false"
334341
class="euiAccordion__button"
342+
id="generated-id"
335343
type="button"
336344
>
337345
<span
@@ -378,6 +386,7 @@ exports[`EuiAccordion props forceState is rendered 1`] = `
378386
aria-controls="7"
379387
aria-expanded="false"
380388
class="euiAccordion__button"
389+
id="generated-id"
381390
type="button"
382391
>
383392
<span
@@ -421,6 +430,7 @@ exports[`EuiAccordion props initialIsOpen is rendered 1`] = `
421430
aria-controls="4"
422431
aria-expanded="true"
423432
class="euiAccordion__button"
433+
id="generated-id"
424434
type="button"
425435
>
426436
<span
@@ -464,6 +474,7 @@ exports[`EuiAccordion props isLoading is rendered 1`] = `
464474
aria-controls="9"
465475
aria-expanded="false"
466476
class="euiAccordion__button"
477+
id="generated-id"
467478
type="button"
468479
>
469480
<span
@@ -514,6 +525,7 @@ exports[`EuiAccordion props isLoadingMessage is rendered 1`] = `
514525
aria-controls="10"
515526
aria-expanded="false"
516527
class="euiAccordion__button"
528+
id="generated-id"
517529
type="button"
518530
>
519531
<span

src/components/accordion/_accordion.scss

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919

2020
&:focus {
2121
.euiAccordion__iconWrapper {
22-
@include euiFocusRing;
23-
color: $euiColorPrimary;
22+
@include euiAccordionIconFocus;
2423
}
2524
}
2625
}
@@ -31,16 +30,14 @@
3130
justify-content: space-between;
3231

3332
.euiAccordion__iconWrapper {
34-
margin-left: $euiSizeS;
35-
margin-right: $euiSizeXS;
33+
@include euiAccordionIconMargin(right);
3634
}
3735
}
3836

3937
.euiAccordion__iconWrapper {
4038
@include size($euiSize);
39+
@include euiAccordionIconMargin;
4140
border-radius: $euiBorderRadius;
42-
margin-right: $euiSizeS;
43-
margin-left: $euiSizeXS;
4441
flex-shrink: 0;
4542

4643
// Nested to override EuiIcon
@@ -54,6 +51,14 @@
5451
}
5552
}
5653

54+
.euiAccordion__iconButton {
55+
@include euiAccordionIconMargin(right);
56+
57+
&:focus {
58+
@include euiAccordionIconFocus;
59+
}
60+
}
61+
5762
.euiAccordion__optionalAction {
5863
flex-shrink: 0;
5964
}
@@ -101,4 +106,4 @@ $paddingSizes: (
101106
.euiAccordion__spinner {
102107
margin-right: $euiSizeXS;
103108
}
104-
}
109+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
@import 'mixins';
12
@import 'accordion';
23
@import 'accordion_form';
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
@mixin euiAccordionIconFocus {
2+
@include euiFocusRing;
3+
color: $euiColorPrimary;
4+
}
5+
6+
@mixin euiAccordionIconMargin($align: left) {
7+
@if $align == left {
8+
margin-left: $euiSizeXS;
9+
margin-right: $euiSizeS;
10+
} @else {
11+
margin-left: $euiSizeS;
12+
margin-right: $euiSizeXS;
13+
}
14+
}

src/components/accordion/accordion.test.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ import { requiredProps } from '../../test/required_props';
2323

2424
import { EuiAccordion } from './accordion';
2525

26+
jest.mock('./../../services/accessibility', () => ({
27+
htmlIdGenerator: () => () => 'generated-id',
28+
}));
29+
2630
let id = 0;
2731
const getId = () => `${id++}`;
2832

src/components/accordion/accordion.tsx

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { EuiIcon } from '../icon';
2626
import { EuiLoadingSpinner } from '../loading';
2727
import { EuiResizeObserver } from '../observer/resize_observer';
2828
import { EuiI18n } from '../i18n';
29+
import { htmlIdGenerator } from '../../services';
2930

3031
const paddingSizeToClassNameMap = {
3132
none: '',
@@ -72,7 +73,6 @@ export type EuiAccordionProps = CommonProps &
7273
paddingSize?: EuiAccordionSize;
7374
/**
7475
* Placement of the arrow indicator, or 'none' to hide it.
75-
* Placing on the `right` doesn't work with `extraAction` and so it will be ignored
7676
*/
7777
arrowDisplay?: 'left' | 'right' | 'none';
7878
/**
@@ -200,13 +200,32 @@ export class EuiAccordion extends Component<
200200
'euiAccordion__icon-isOpen': isOpen,
201201
});
202202

203-
let icon;
203+
const iconWrapperClasses = classNames('euiAccordion__iconWrapper', {
204+
euiAccordion__iconButton: extraAction && arrowDisplay === 'right',
205+
});
206+
207+
let baseIcon;
204208
if (arrowDisplay !== 'none') {
205-
icon = (
206-
<span className="euiAccordion__iconWrapper">
207-
<EuiIcon className={iconClasses} type="arrowRight" size="m" />
208-
</span>
209+
baseIcon = <EuiIcon className={iconClasses} type="arrowRight" size="m" />;
210+
}
211+
212+
let icon;
213+
let iconButton;
214+
const buttonId = htmlIdGenerator()();
215+
if (extraAction && arrowDisplay === 'right') {
216+
iconButton = (
217+
<button
218+
aria-controls={id}
219+
aria-expanded={isOpen}
220+
aria-labelledby={buttonId}
221+
tabIndex={-1}
222+
className={iconWrapperClasses}
223+
onClick={this.onToggle}>
224+
{baseIcon}
225+
</button>
209226
);
227+
} else if (arrowDisplay !== 'none') {
228+
icon = <span className={iconWrapperClasses}>{baseIcon}</span>;
210229
}
211230

212231
let optionalAction = null;
@@ -245,6 +264,7 @@ export class EuiAccordion extends Component<
245264
<div className={classes} {...rest}>
246265
<div className="euiAccordion__triggerWrapper">
247266
<button
267+
id={buttonId}
248268
aria-controls={id}
249269
aria-expanded={isOpen}
250270
onClick={this.onToggle}
@@ -260,6 +280,7 @@ export class EuiAccordion extends Component<
260280
</span>
261281
</button>
262282
{optionalAction}
283+
{iconButton}
263284
</div>
264285

265286
<div

src/components/collapsible_nav/collapsible_nav_group/__snapshots__/collapsible_nav_group.test.tsx.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ exports[`EuiCollapsibleNavGroup when isCollapsible is true will render an accord
246246
aria-controls="id"
247247
aria-expanded="false"
248248
class="euiAccordion__button euiAccordion__buttonReverse euiCollapsibleNavGroup__heading"
249+
id="generated-id"
249250
type="button"
250251
>
251252
<span

src/components/collapsible_nav/collapsible_nav_group/collapsible_nav_group.test.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ import { requiredProps } from '../../../test/required_props';
2323

2424
import { EuiCollapsibleNavGroup, BACKGROUNDS } from './collapsible_nav_group';
2525

26+
jest.mock('./../../../services/accessibility', () => ({
27+
htmlIdGenerator: () => () => 'generated-id',
28+
}));
29+
2630
describe('EuiCollapsibleNavGroup', () => {
2731
test('is rendered', () => {
2832
const component = render(

0 commit comments

Comments
 (0)