Skip to content

Commit 76ca3cf

Browse files
feat: added the ability to close the hint using the keyboard
1 parent 14c662d commit 76ca3cf

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

src/course-home/progress-tab/grades/grade-summary/GradeSummaryHeader.jsx

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import React, { useState } from 'react';
12
import PropTypes from 'prop-types';
23
import { useIntl } from '@edx/frontend-platform/i18n';
34
import {
@@ -6,6 +7,7 @@ import {
67
OverlayTrigger,
78
Stack,
89
Tooltip,
10+
IconButton,
911
} from '@openedx/paragon';
1012
import { InfoOutline, Locked } from '@openedx/paragon/icons';
1113
import { useContextId } from '../../../../data/hooks';
@@ -20,6 +22,13 @@ const GradeSummaryHeader = ({ allOfSomeAssignmentTypeIsLocked }) => {
2022
verifiedMode,
2123
gradesFeatureIsFullyLocked,
2224
} = useModel('progress', courseId);
25+
const [showTooltip, setShowTooltip] = useState(false);
26+
27+
const handleKeyDown = (event) => {
28+
if (event.key === 'Escape') {
29+
setShowTooltip(false);
30+
}
31+
};
2332

2433
return (
2534
<Stack gap={2} className="mb-3">
@@ -34,9 +43,13 @@ const GradeSummaryHeader = ({ allOfSomeAssignmentTypeIsLocked }) => {
3443
</Tooltip>
3544
)}
3645
>
37-
<Icon
46+
<IconButton
47+
onClick={() => { setShowTooltip(!showTooltip); }}
48+
onBlur={() => { setShowTooltip(false); }}
49+
onKeyDown={handleKeyDown}
3850
alt={intl.formatMessage(messages.gradeSummaryTooltipAlt)}
3951
src={InfoOutline}
52+
className="mb-3"
4053
size="sm"
4154
/>
4255
</OverlayTrigger>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import React from 'react';
2+
import {
3+
render, screen, waitFor,
4+
} from '@testing-library/react';
5+
import userEvent from '@testing-library/user-event';
6+
import { useSelector } from 'react-redux';
7+
import { IntlProvider } from 'react-intl';
8+
9+
import GradeSummaryHeader from './GradeSummaryHeader';
10+
import { useModel } from '../../../../generic/model-store';
11+
import messages from '../messages';
12+
13+
jest.mock('react-redux', () => ({
14+
useSelector: jest.fn(),
15+
}));
16+
17+
jest.mock('../../../../generic/model-store', () => ({
18+
useModel: jest.fn(),
19+
}));
20+
21+
describe('GradeSummaryHeader', () => {
22+
beforeEach(() => {
23+
useSelector.mockImplementation((selector) => selector({
24+
courseHome: { courseId: 'test-course-id' },
25+
}));
26+
useModel.mockReturnValue({ gradesFeatureIsFullyLocked: false });
27+
});
28+
29+
const renderComponent = (props = {}) => {
30+
render(
31+
<IntlProvider locale="en" messages={messages}>
32+
<GradeSummaryHeader
33+
intl={{ formatMessage: jest.fn((msg) => msg.defaultMessage) }}
34+
allOfSomeAssignmentTypeIsLocked={false}
35+
{...props}
36+
/>
37+
</IntlProvider>,
38+
);
39+
};
40+
41+
it('visible the tooltip when Escape is pressed', async () => {
42+
renderComponent();
43+
44+
const iconButton = screen.getByRole('button', {
45+
name: messages.gradeSummaryTooltipAlt.defaultMessage,
46+
});
47+
48+
userEvent.click(iconButton);
49+
50+
await waitFor(() => {
51+
expect(screen.getByText(messages.gradeSummaryTooltipBody.defaultMessage)).toBeVisible();
52+
});
53+
});
54+
});

0 commit comments

Comments
 (0)