Skip to content

Commit 23baf0b

Browse files
fix: snackbar: added focus to close button in snackbar (#955)
* fix: snackbar: added focus to close button in snackbar * fix: snackbar: returned focus to serve snack button * test: snackBar: updated test cases --------- Co-authored-by: ypatadia-eightfold <[email protected]>
1 parent 1ef34c0 commit 23baf0b

File tree

5 files changed

+29
-10
lines changed

5 files changed

+29
-10
lines changed

src/components/InfoBar/InfoBar.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import React, { FC, Ref, useContext, useEffect, useState } from 'react';
3+
import React, { FC, Ref, useContext, useEffect, useRef, useState } from 'react';
44
import GradientContext, { Gradient } from '../ConfigProvider/GradientContext';
55
import { OcThemeName } from '../ConfigProvider';
66
import ThemeContext, {
@@ -48,6 +48,7 @@ export const InfoBar: FC<InfoBarsProps> = React.forwardRef(
4848
type = InfoBarType.neutral,
4949
...rest
5050
} = props;
51+
const closeButtonRef = useRef<HTMLButtonElement>(null);
5152

5253
const contextualGradient: Gradient = useContext(GradientContext);
5354
const mergedGradient: boolean = configContextProps.noGradientContext
@@ -82,6 +83,12 @@ export const InfoBar: FC<InfoBarsProps> = React.forwardRef(
8283
);
8384
}, [mergedLocale]);
8485

86+
setTimeout(() => {
87+
if (closeButtonRef.current) {
88+
closeButtonRef.current.focus();
89+
}
90+
}, 1000);
91+
8592
const infoBarClassNames: string = mergeClasses([
8693
styles.infoBar,
8794
{ [styles.bordered]: !!bordered },
@@ -129,7 +136,6 @@ export const InfoBar: FC<InfoBarsProps> = React.forwardRef(
129136
className={infoBarClassNames}
130137
ref={ref}
131138
style={style}
132-
role={role}
133139
>
134140
<Icon
135141
path={getIconName()}
@@ -141,7 +147,9 @@ export const InfoBar: FC<InfoBarsProps> = React.forwardRef(
141147
contentWrapperClassNames,
142148
])}
143149
>
144-
<div className={messageClasses}>{content}</div>
150+
<div className={messageClasses} role={role}>
151+
{content}
152+
</div>
145153
{actionButtonProps && (
146154
<Button
147155
buttonWidth={ButtonWidth.fitContent}
@@ -162,6 +170,7 @@ export const InfoBar: FC<InfoBarsProps> = React.forwardRef(
162170
iconProps={{ path: closeIcon }}
163171
onClick={onClose}
164172
shape={ButtonShape.Round}
173+
ref={closeButtonRef}
165174
transparent
166175
{...closeButtonProps}
167176
classNames={mergeClasses([

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ exports[`InfoBar InfoBar is Disruptive 1`] = `
44
<div>
55
<div
66
class="info-bar disruptive"
7-
role="alert"
87
>
98
<span
109
aria-hidden="false"
@@ -27,6 +26,7 @@ exports[`InfoBar InfoBar is Disruptive 1`] = `
2726
>
2827
<div
2928
class="message body2"
29+
role="alert"
3030
>
3131
InfoBar test disruptive
3232
</div>
@@ -39,7 +39,6 @@ exports[`InfoBar InfoBar is Neutral 1`] = `
3939
<div>
4040
<div
4141
class="info-bar neutral"
42-
role="alert"
4342
>
4443
<span
4544
aria-hidden="false"
@@ -62,6 +61,7 @@ exports[`InfoBar InfoBar is Neutral 1`] = `
6261
>
6362
<div
6463
class="message body2"
64+
role="alert"
6565
>
6666
InfoBar test neutral
6767
</div>
@@ -74,7 +74,6 @@ exports[`InfoBar InfoBar is Positive 1`] = `
7474
<div>
7575
<div
7676
class="info-bar positive"
77-
role="alert"
7877
>
7978
<span
8079
aria-hidden="false"
@@ -97,6 +96,7 @@ exports[`InfoBar InfoBar is Positive 1`] = `
9796
>
9897
<div
9998
class="message body2"
99+
role="alert"
100100
>
101101
InfoBar test positive
102102
</div>
@@ -109,7 +109,6 @@ exports[`InfoBar InfoBar is Warning 1`] = `
109109
<div>
110110
<div
111111
class="info-bar warning"
112-
role="alert"
113112
>
114113
<span
115114
aria-hidden="false"
@@ -132,6 +131,7 @@ exports[`InfoBar InfoBar is Warning 1`] = `
132131
>
133132
<div
134133
class="message body2"
134+
role="alert"
135135
>
136136
InfoBar test warning
137137
</div>
@@ -144,7 +144,6 @@ exports[`InfoBar InfoBar is bordered 1`] = `
144144
<div>
145145
<div
146146
class="info-bar bordered neutral"
147-
role="alert"
148147
>
149148
<span
150149
aria-hidden="false"
@@ -167,6 +166,7 @@ exports[`InfoBar InfoBar is bordered 1`] = `
167166
>
168167
<div
169168
class="message body2"
169+
role="alert"
170170
>
171171
InfoBar test border
172172
</div>
@@ -179,7 +179,6 @@ exports[`InfoBar Renders a custom icon when the icon prop uses a custom icon 1`]
179179
<div>
180180
<div
181181
class="info-bar neutral"
182-
role="alert"
183182
>
184183
<span
185184
aria-hidden="false"
@@ -202,6 +201,7 @@ exports[`InfoBar Renders a custom icon when the icon prop uses a custom icon 1`]
202201
>
203202
<div
204203
class="message body2"
204+
role="alert"
205205
>
206206
InfoBar test icon
207207
</div>
@@ -214,7 +214,6 @@ exports[`InfoBar Renders without crashing 1`] = `
214214
<div>
215215
<div
216216
class="info-bar neutral"
217-
role="alert"
218217
>
219218
<span
220219
aria-hidden="false"
@@ -237,6 +236,7 @@ exports[`InfoBar Renders without crashing 1`] = `
237236
>
238237
<div
239238
class="message body2"
239+
role="alert"
240240
>
241241
InfoBar test render
242242
</div>

src/components/Snackbar/Snackbar.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const Snackbar: FC<SnackbarProps> = ({ classNames, ...rest }) => {
1111
const snackbarClasses = mergeClasses([styles.snackbar, classNames]);
1212
return (
1313
<InfoBar
14+
tabIndex={0}
1415
{...rest}
1516
classNames={snackbarClasses}
1617
contentClassNames={styles.content}

src/components/Snackbar/SnackbarContainer.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export const SnackbarContainer: FC<SnackbarContainerProps> = ({
6767
>
6868
{getPositionSnacks(position).map((snack) => (
6969
<Snackbar
70+
tabIndex={-1}
7071
{...snack}
7172
key={snack.id}
7273
onClose={() => {

src/components/Snackbar/snack.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { InfoBarType } from '../InfoBar';
1111

1212
const DEFAULT_POSITION: SnackbarPosition = 'top-center';
1313

14+
let focusedElementRef: HTMLElement | null = null;
15+
1416
export const SNACK_EVENTS: Record<string, string> = {
1517
SERVE: 'serveSnack',
1618
EAT: 'eatSnack',
@@ -30,6 +32,9 @@ export const serve = (props: SnackbarProps): VoidFunction => {
3032
if (canUseDocElement()) {
3133
document.dispatchEvent(serveSnackEvent);
3234
}
35+
36+
focusedElementRef = document.activeElement as HTMLElement;
37+
3338
if (!props.closable || props.actionButtonProps) {
3439
setTimeout(() => {
3540
eat(id);
@@ -48,6 +53,9 @@ export const eat = (snackId: string): void => {
4853
if (canUseDocElement()) {
4954
document.dispatchEvent(removeSnackEvent);
5055
}
56+
if (focusedElementRef) {
57+
focusedElementRef.focus();
58+
}
5159
};
5260

5361
export const serveNeutral = (props: SnackbarProps) =>

0 commit comments

Comments
 (0)