diff --git a/package.json b/package.json
index 78c980805..36ab7086e 100644
--- a/package.json
+++ b/package.json
@@ -77,7 +77,7 @@
},
{
"path": "./build/releases/OneSignalSDK.page.es6.js",
- "limit": "42.65 kB",
+ "limit": "42.7 kB",
"gzip": true
},
{
diff --git a/src/page/bell/Bell.test.ts b/src/page/bell/Bell.test.ts
index 39f850f19..6bb2f7092 100644
--- a/src/page/bell/Bell.test.ts
+++ b/src/page/bell/Bell.test.ts
@@ -156,6 +156,36 @@ describe('Bell', () => {
);
}
+ test('launcher button has a default accessible name', async () => {
+ mockCreateDeps();
+ const bell = new Bell({ enable: true, showLauncherAfter: 0 });
+ await bell._create();
+
+ expect(bell._button._element!.getAttribute('aria-label')).toBe('Manage notifications');
+ });
+
+ test('launcher button accessible name is configurable via text', async () => {
+ mockCreateDeps();
+ const bell = new Bell({
+ enable: true,
+ showLauncherAfter: 0,
+ // @ts-expect-error - partial text config
+ text: { 'launcher.button.aria-label': 'Notification preferences' },
+ });
+ await bell._create();
+
+ expect(bell._button._element!.getAttribute('aria-label')).toBe('Notification preferences');
+ });
+
+ test('bell svg is hidden from the accessibility tree', async () => {
+ mockCreateDeps();
+ const bell = new Bell({ enable: true, showLauncherAfter: 0 });
+ await bell._create();
+
+ const svg = bell._button._element!.querySelector('svg')!;
+ expect(svg.getAttribute('aria-hidden')).toBe('true');
+ });
+
test('mouseleave on launcher blurs the button', async () => {
mockCreateDeps();
const bell = new Bell({ enable: true, showLauncherAfter: 0 });
diff --git a/src/page/bell/Bell.ts b/src/page/bell/Bell.ts
index 57b485bd8..4efd2e194 100755
--- a/src/page/bell/Bell.ts
+++ b/src/page/bell/Bell.ts
@@ -21,7 +21,7 @@ import Dialog from './Dialog';
import Launcher from './Launcher';
import Message from './Message';
-const logoSvg = ``;
+const logoSvg = ``;
const DEFAULT_SIZE: BellSize = 'medium';
const DEFAULT_POSITION: BellPosition = 'bottom-right';
@@ -31,7 +31,10 @@ const VALID_SIZES: readonly string[] = ['small', 'medium', 'large'];
const VALID_POSITIONS: readonly string[] = ['bottom-left', 'bottom-right'];
const VALID_THEMES: readonly string[] = ['default', 'inverse'];
+const DEFAULT_LAUNCHER_LABEL = 'Manage notifications';
+
const DEFAULT_TEXT: BellText = {
+ 'launcher.button.aria-label': DEFAULT_LAUNCHER_LABEL,
'tip.state.unsubscribed': 'Subscribe to notifications',
'tip.state.subscribed': "You're subscribed to notifications",
'tip.state.blocked': "You've blocked notifications",
@@ -213,6 +216,10 @@ export default class Bell {
'beforeend',
'',
);
+ this._button._element?.setAttribute(
+ 'aria-label',
+ this._options.text['launcher.button.aria-label'] || DEFAULT_LAUNCHER_LABEL,
+ );
addDomElement(
this._launcher._selector,
'beforeend',
diff --git a/src/page/bell/Message.ts b/src/page/bell/Message.ts
index d1491beb5..d0a80d806 100755
--- a/src/page/bell/Message.ts
+++ b/src/page/bell/Message.ts
@@ -64,6 +64,6 @@ export default class Message {
_getTipForState(): string {
const key = TIP_KEYS[this._bell._state];
- return key ? this._bell._options.text[key] : '';
+ return key ? (this._bell._options.text[key] ?? '') : '';
}
}
diff --git a/src/shared/prompts/types.ts b/src/shared/prompts/types.ts
index ca095a72a..d1404ca01 100644
--- a/src/shared/prompts/types.ts
+++ b/src/shared/prompts/types.ts
@@ -116,6 +116,7 @@ export type BellSize = 'small' | 'medium' | 'large';
export type BellPosition = 'bottom-left' | 'bottom-right';
export interface BellText {
+ 'launcher.button.aria-label'?: string;
'tip.state.unsubscribed': string;
'tip.state.subscribed': string;
'tip.state.blocked': string;