Skip to content

Commit 6b98d10

Browse files
arbiralihinakhadim
andauthored
Toggle the theme on pressing the enter key (#27)
* fix: Toggle the theme on pressing the enter key * fix: Fix linter issue * feat: Adds accessible name to the theme tollger * fix: add test-case for coverage 100% * chore: resolves lint issues --------- Co-authored-by: hinakhadim <hina.khadim@arbisoft.com>
1 parent fedab6c commit 6b98d10

File tree

3 files changed

+73
-3
lines changed

3 files changed

+73
-3
lines changed

src/Header.messages.jsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ const messages = defineMessages({
2121
defaultMessage: 'Schools & Partners',
2222
description: 'Link to the schools and partners landing page',
2323
},
24+
'header.user.theme': {
25+
id: 'header.user.theme',
26+
defaultMessage: 'Toggle Theme',
27+
description: 'Toggle between light and dark theme',
28+
},
2429
'header.user.menu.dashboard': {
2530
id: 'header.user.menu.dashboard',
2631
defaultMessage: 'Dashboard',

src/ThemeToggleButton.jsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ import { getConfig } from '@edx/frontend-platform';
33
import Cookies from 'universal-cookie';
44
import { Icon } from '@openedx/paragon';
55
import { WbSunny, Nightlight } from '@openedx/paragon/icons';
6+
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
7+
import messages from './Header.messages';
68

79
const themeCookie = 'indigo-toggle-dark';
810
const themeCookieExpiry = 90; // days
911

10-
const ThemeToggleButton = () => {
12+
const ThemeToggleButton = ({ intl }) => {
1113
const cookies = new Cookies();
1214
const isThemeToggleEnabled = getConfig().INDIGO_ENABLE_DARK_TOGGLE;
1315

@@ -75,6 +77,12 @@ const ThemeToggleButton = () => {
7577
}
7678
};
7779

80+
const hanldeKeyUp = (event) => {
81+
if (event.key === 'Enter') {
82+
onToggleTheme();
83+
}
84+
};
85+
7886
if (!isThemeToggleEnabled) {
7987
return <div />;
8088
}
@@ -84,7 +92,7 @@ const ThemeToggleButton = () => {
8492
<div className="light-theme-icon"><Icon src={WbSunny} /></div>
8593
<div className="toggle-switch">
8694
<label htmlFor="theme-toggle-checkbox" className="switch">
87-
<input id="theme-toggle-checkbox" defaultChecked={cookies.get(themeCookie) === 'dark'} onChange={onToggleTheme} type="checkbox" />
95+
<input id="theme-toggle-checkbox" defaultChecked={cookies.get(themeCookie) === 'dark'} onChange={onToggleTheme} onKeyUp={hanldeKeyUp} type="checkbox" title={intl.formatMessage(messages['header.user.theme'])} />
8896
<span className="slider round" />
8997
</label>
9098
</div>
@@ -93,4 +101,9 @@ const ThemeToggleButton = () => {
93101
);
94102
};
95103

96-
export default ThemeToggleButton;
104+
ThemeToggleButton.propTypes = {
105+
// i18n
106+
intl: intlShape.isRequired,
107+
};
108+
109+
export default injectIntl(ThemeToggleButton);

src/ThemeToggleButton.test.jsx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/* eslint-disable react/prop-types */
2+
import React from 'react';
3+
import { IntlProvider } from '@edx/frontend-platform/i18n';
4+
import { render, fireEvent } from '@testing-library/react';
5+
import { getConfig } from '@edx/frontend-platform';
6+
import ThemeToggleButton from './ThemeToggleButton';
7+
8+
jest.mock('@edx/frontend-platform', () => ({
9+
getConfig: jest.fn(),
10+
}));
11+
12+
const mockCookiesGet = jest.fn();
13+
const mockCookiesSet = jest.fn();
14+
jest.mock('universal-cookie', () => jest.fn().mockImplementation(() => ({
15+
get: mockCookiesGet, // Simulate initial light mode
16+
set: mockCookiesSet,
17+
})));
18+
19+
describe('ThemeToggleButton', () => {
20+
beforeEach(() => {
21+
getConfig.mockReturnValue({
22+
LMS_BASE_URL: 'https://fake.url',
23+
INDIGO_ENABLE_DARK_TOGGLE: true,
24+
});
25+
26+
// Reset body class
27+
document.body.classList.remove('indigo-dark-theme');
28+
});
29+
30+
it('calls onToggleTheme when Enter key is pressed', () => {
31+
mockCookiesGet.mockReturnValue('light');
32+
33+
const { container } = render(
34+
<IntlProvider locale="en" messages={{}}>
35+
<ThemeToggleButton />
36+
</IntlProvider>,
37+
);
38+
const checkbox = container.querySelector('#theme-toggle-checkbox');
39+
checkbox.focus();
40+
fireEvent.keyUp(checkbox, { key: 'Enter' });
41+
42+
expect(mockCookiesSet).toHaveBeenCalledWith(
43+
'indigo-toggle-dark',
44+
'dark',
45+
expect.objectContaining({
46+
domain: 'fake.url',
47+
path: '/',
48+
expires: expect.any(Date),
49+
}),
50+
);
51+
});
52+
});

0 commit comments

Comments
 (0)