Skip to content

Commit 298c51d

Browse files
authored
Merge pull request #3101 from Chaitanya1672/fix/missing-skip-link
Add skip link for better keyboard accessibility Fix-#3084
2 parents c48ce1e + 1022cee commit 298c51d

File tree

6 files changed

+71
-0
lines changed

6 files changed

+71
-0
lines changed

client/components/SkipLink.jsx

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React, { useState } from 'react';
2+
import classNames from 'classnames';
3+
import PropTypes from 'prop-types';
4+
import { useTranslation } from 'react-i18next';
5+
6+
const SkipLink = ({ targetId, text }) => {
7+
const [focus, setFocus] = useState(false);
8+
const { t } = useTranslation();
9+
const handleFocus = () => {
10+
setFocus(true);
11+
};
12+
13+
const handleBlur = () => {
14+
setFocus(false);
15+
};
16+
const linkClasses = classNames('skip_link', { focus });
17+
18+
return (
19+
<a
20+
href={`#${targetId}`}
21+
className={linkClasses}
22+
onFocus={handleFocus}
23+
onBlur={handleBlur}
24+
>
25+
{t(`SkipLink.${text}`)}
26+
</a>
27+
);
28+
};
29+
30+
SkipLink.propTypes = {
31+
targetId: PropTypes.string.isRequired,
32+
text: PropTypes.string.isRequired
33+
};
34+
35+
export default SkipLink;

client/index.jsx

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Routing from './routes';
99
import ThemeProvider from './modules/App/components/ThemeProvider';
1010
import Loader from './modules/App/components/loader';
1111
import './i18n';
12+
import SkipLink from './components/SkipLink';
1213

1314
require('./styles/main.scss');
1415

@@ -23,6 +24,7 @@ const App = () => (
2324
<Provider store={store}>
2425
<ThemeProvider>
2526
<Router history={browserHistory}>
27+
<SkipLink targetId="play-sketch" text="PlaySketch" />
2628
<Routing />
2729
</Router>
2830
</ThemeProvider>

client/modules/IDE/components/Header/Toolbar.jsx

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ const Toolbar = (props) => {
6161
</button>
6262
<button
6363
className={playButtonClass}
64+
id="play-sketch"
6465
onClick={() => {
6566
props.syncFileContent();
6667
dispatch(startSketch());
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
@use "sass:math";
2+
3+
.skip_link {
4+
left: 50%;
5+
transform: translateX(-50%);
6+
top: 1%;
7+
clip: rect(0 0 0 0);
8+
overflow: hidden;
9+
position: absolute;
10+
border-radius: 3px;
11+
white-space: nowrap;
12+
vertical-align: middle;
13+
background-color: transparent;
14+
font-size: #{math.div(12, $base-font-size)}rem;
15+
line-height: #{math.div(50, $base-font-size)}rem;line-height: 11px;
16+
padding: #{math.div(10, $base-font-size)}rem #{math.div(10, $base-font-size)}rem;
17+
background: #fff;
18+
display: inline-block;
19+
text-transform: uppercase;
20+
transition: none;
21+
z-index: 5;
22+
}
23+
24+
.skip_link:focus {
25+
clip: auto;
26+
overflow: visible;
27+
width: auto;
28+
height: auto;
29+
}

client/styles/main.scss

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
@import 'components/collection';
5555
@import 'components/collection-create';
5656
@import 'components/quick-add';
57+
@import 'components/skip-link';
5758

5859
@import 'layout/dashboard';
5960
@import 'layout/ide';

translations/locales/en-US/translations.json

+3
Original file line numberDiff line numberDiff line change
@@ -621,5 +621,8 @@
621621
"PrivacyPolicy": "Privacy Policy",
622622
"TermsOfUse": "Terms of Use",
623623
"CodeOfConduct": "Code of Conduct"
624+
},
625+
"SkipLink": {
626+
"PlaySketch": "Skip to Play Sketch"
624627
}
625628
}

0 commit comments

Comments
 (0)