kopia lustrzana https://github.com/wagtail/wagtail
Add global tab-through focus outline styles
rodzic
c9e740324c
commit
278cda67ab
|
@ -0,0 +1,11 @@
|
|||
// stylelint-disable declaration-no-important
|
||||
// Set global focus outline styles so they are consistent across the UI,
|
||||
// without individual components having to explicitly define focus styles.
|
||||
// Using !important because we want to enforce only one style is used across the UI.
|
||||
.focus-outline-on *:focus {
|
||||
outline: 3px solid $color-focus-outline !important;
|
||||
}
|
||||
|
||||
.focus-outline-off *:focus {
|
||||
outline: none !important;
|
||||
}
|
|
@ -70,9 +70,14 @@ $color-button-no: $color-red-dark;
|
|||
$color-button-no-hover: darken($color-button-no, 20%);
|
||||
$color-button-warning: $color-orange-dark;
|
||||
$color-button-warning-hover: darken($color-button-warning, 20%);
|
||||
|
||||
$color-link: $color-teal-darker;
|
||||
$color-link-hover: $color-teal-dark;
|
||||
|
||||
// The focus outline color is defined without reusing a named color variable
|
||||
// because it shouldn’t be reused for anything else in the UI.
|
||||
$color-focus-outline: #ffbf47;
|
||||
|
||||
$color-text-base: darken($color-white, 85);
|
||||
$color-text-input: darken($color-white, 90);
|
||||
|
||||
|
|
|
@ -144,6 +144,7 @@ These are classes that provide overrides.
|
|||
@import 'overrides/utilities.hidden';
|
||||
@import 'overrides/utilities.text';
|
||||
@import 'overrides/utilities.dropdowns';
|
||||
@import 'overrides/utilities.focus';
|
||||
|
||||
// Legacy utilities
|
||||
@import 'overrides/utilities.text.legacy';
|
||||
|
|
|
@ -13,6 +13,7 @@ import Explorer, {
|
|||
ExplorerToggle,
|
||||
initExplorer,
|
||||
} from './components/Explorer';
|
||||
import { initFocusOutline } from './utils/focus';
|
||||
|
||||
export {
|
||||
Button,
|
||||
|
@ -24,4 +25,5 @@ export {
|
|||
Explorer,
|
||||
ExplorerToggle,
|
||||
initExplorer,
|
||||
initFocusOutline,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
const OUTLINE_ON = 'focus-outline-on';
|
||||
const OUTLINE_OFF = 'focus-outline-off';
|
||||
|
||||
const toggleFocusOutline = (isOn) => {
|
||||
document.body.classList.toggle(OUTLINE_OFF, !isOn);
|
||||
document.body.classList.toggle(OUTLINE_ON, isOn);
|
||||
};
|
||||
|
||||
const removeFocusOutline = toggleFocusOutline.bind(null, false);
|
||||
const addFocusOutline = toggleFocusOutline.bind(null, true);
|
||||
|
||||
/**
|
||||
* Adds a heavy focus outline to the UI, only for users who tab through the page.
|
||||
* The outline is not useful with touch or mouse input – these remove the outline.
|
||||
*/
|
||||
export const initFocusOutline = () => {
|
||||
// Focus outline styles are added by default in the HTML, so they work without JS enabled.
|
||||
removeFocusOutline();
|
||||
|
||||
window.addEventListener('mousedown', removeFocusOutline);
|
||||
window.addEventListener('touchstart', removeFocusOutline);
|
||||
|
||||
window.addEventListener('keydown', e => {
|
||||
const isTabKey = e.keyCode === 9;
|
||||
|
||||
if (isTabKey) {
|
||||
addFocusOutline();
|
||||
}
|
||||
});
|
||||
};
|
|
@ -0,0 +1,48 @@
|
|||
import { initFocusOutline } from './focus';
|
||||
|
||||
describe('initFocusOutline', () => {
|
||||
beforeEach(() => {
|
||||
document.body.classList.add('focus-outline-on');
|
||||
});
|
||||
|
||||
it('removes styles on init', () => {
|
||||
initFocusOutline();
|
||||
expect(document.body.className).toBe('focus-outline-off');
|
||||
});
|
||||
|
||||
it('adds styles when tabbing', () => {
|
||||
initFocusOutline();
|
||||
window.dispatchEvent(
|
||||
Object.assign(new Event('keydown'), {
|
||||
keyCode: 9
|
||||
})
|
||||
);
|
||||
expect(document.body.className).toBe('focus-outline-on');
|
||||
});
|
||||
|
||||
it('does not change styles when using keys that are not tab', () => {
|
||||
initFocusOutline();
|
||||
window.dispatchEvent(new Event('keydown'));
|
||||
expect(document.body.className).toBe('focus-outline-off');
|
||||
});
|
||||
|
||||
it('removes styles when using a mouse', () => {
|
||||
window.dispatchEvent(
|
||||
Object.assign(new Event('keydown'), {
|
||||
keyCode: 9
|
||||
})
|
||||
);
|
||||
window.dispatchEvent(new Event('mousedown'));
|
||||
expect(document.body.className).toBe('focus-outline-off');
|
||||
});
|
||||
|
||||
it('removes styles when using a touch screen', () => {
|
||||
window.dispatchEvent(
|
||||
Object.assign(new Event('keydown'), {
|
||||
keyCode: 9
|
||||
})
|
||||
);
|
||||
window.dispatchEvent(new Event('touchstart'));
|
||||
expect(document.body.className).toBe('focus-outline-off');
|
||||
});
|
||||
});
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { initExplorer, Icon, Portal } from 'wagtail-client';
|
||||
import { initExplorer, Icon, Portal, initFocusOutline } from 'wagtail-client';
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// Run react-axe in development only, so it does not affect performance
|
||||
|
@ -26,4 +26,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
if (explorerNode && toggleNode) {
|
||||
initExplorer(explorerNode, toggleNode);
|
||||
}
|
||||
|
||||
initFocusOutline();
|
||||
});
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
{% block branding_favicon %}{% endblock %}
|
||||
</head>
|
||||
<body id="wagtail" class="{% block bodyclass %}{% endblock %} {% if messages %}has-messages{% endif %}">
|
||||
<body id="wagtail" class="{% block bodyclass %}{% endblock %} {% if messages %}has-messages{% endif %} focus-outline-on">
|
||||
<!--[if lt IE 9]>
|
||||
<p class="capabilitymessage">{% blocktrans %}You are using an <strong>outdated</strong> browser not supported by this software. Please <a href="http://browsehappy.com/">upgrade your browser</a>.{% endblocktrans %}</p>
|
||||
<![endif]-->
|
||||
|
|
Ładowanie…
Reference in New Issue