Skip to content

Instantly share code, notes, and snippets.

@e1en0r
Last active October 11, 2019 19:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save e1en0r/ed8b0c9233e8912325a3e065c53952fa to your computer and use it in GitHub Desktop.
Save e1en0r/ed8b0c9233e8912325a3e065c53952fa to your computer and use it in GitHub Desktop.
React accessibility provider
import React from 'react';
export const AccessibilityContext = React.createContext({
accessible: undefined,
setAccessible: (/* accessible */) => {},
});
import React, { useCallback, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { AccessibilityContext } from './AccessibilityContext';
export function AccessibilityProvider({ initialAccessible, children }) {
const [accessible, setAccessible] = useState(initialAccessible);
const handleKeyDown = useCallback(event => {
if (!['input', 'select', 'textarea'].includes(event.target.tagName.toLowerCase())) {
setAccessible(true);
}
}, [setAccessible]);
const handleMouseDown = useCallback(() => setAccessible(false), [setAccessible]);
useEffect(() => {
window.addEventListener('mousedown', handleMouseDown, { passive: true });
window.addEventListener('keydown', handleKeyDown, { passive: true });
return () => {
window.removeEventListener('mousedown', handleMouseDown);
window.removeEventListener('keydown', handleKeyDown);
};
}, [handleMouseDown, handleKeyDown]);
return (
<AccessibilityContext.Provider
value={{
accessible,
setAccessible,
}}
>
{children}
</AccessibilityContext.Provider>
);
}
AccessibilityProvider.defaultProps = {
initialAccessible: false,
};
AccessibilityProvider.propTypes = {
children: PropTypes.node.isRequired,
initialAccessible: PropTypes.bool,
};
import React, { useContext } from 'react';
import { cx } from 'emotion';
import { AccessibilityContext } from './AccessibilityContext';
import styles from './example.module.css';
export const Example = ({ children }) => {
const { accessible } = useContext(AccessibilityContext);
return (
<div
className={cx(
styles.example,
accessible && styles['is-accessible'],
)}
>
{children}
</div>
);
};
.example.is-accessible:focus {
border: 1px solid blue;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment