Switch focus outlines implementation to `:focus-visible` for cross-browser consistency. Fix #7994 (#8113)

Co-authored-by: Thibaud Colas <thibaudcolas@gmail.com>
pull/8111/head
PaarthAgarwal 2022-03-15 17:03:12 +05:30 zatwierdzone przez GitHub
rodzic 7067c81604
commit 6a84cf4583
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
9 zmienionych plików z 11 dodań i 90 usunięć

Wyświetl plik

@ -19,6 +19,7 @@ Changelog
* Adopt [MyST](https://myst-parser.readthedocs.io/en/latest/) for parsing documentation written in Markdown, replaces recommonmark (LB (Ben Johnston), Thibaud Colas)
* Installing docs extras requirements in CircleCI so issues with the docs requirements are picked up earlier (Thibaud Colas)
* Remove core usage of jinjalint and migrate to curlylint to resolve dependency incompatibility issues (Thibaud Colas)
* Switch focus outlines implementation to `:focus-visible` for cross-browser consistency (Paarth Agarwal)
* Fix: When using `simple_translations` ensure that the user is redirected to the page edit view when submitting for a single locale (Mitchel Cabuloy)
* Fix: When previewing unsaved changes to `Form` pages, ensure that all added fields are correctly shown in the preview (Joshua Munn)
* Fix: When Documents (e.g. PDFs) have been configured to be served inline via `WAGTAILDOCS_CONTENT_TYPES` & `WAGTAILDOCS_INLINE_CONTENT_TYPES` ensure that the filename is correctly set in the `Content-Disposition` header so that saving the files will use the correct filename (John-Scott Atlakson)

Wyświetl plik

@ -564,6 +564,7 @@ Contributors
* Joshua Munn
* Gianluca De Cola
* Sage Abdullah
* Paarth Agarwal
Translators
===========

Wyświetl plik

@ -2,10 +2,15 @@
// 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 {
// Remove :focus selectors once we stop supporting Safari 15.4.
*:focus {
outline: $focus-outline-width solid $color-focus-outline !important;
}
.focus-outline-off *:focus {
*:focus:not(:focus-visible) {
outline: none !important;
}
*:focus-visible {
outline: $focus-outline-width solid $color-focus-outline !important;
}

Wyświetl plik

@ -7,7 +7,6 @@ import { MainMenuModuleDefinition } from './modules/MainMenu';
import { PageExplorerMenuItemDefinition } from './menu/PageExplorerMenuItem';
import { LinkMenuItemDefinition } from './menu/LinkMenuItem';
import { SubMenuItemDefinition } from './menu/SubMenuItem';
import { initFocusOutline } from '../../utils/focus';
export default {
title: 'Sidebar/Sidebar',
@ -212,11 +211,6 @@ function renderSidebarStory(
modules: ModuleDefinition[],
{ rtl = false, strings = null }: RenderSidebarStoryOptions = {},
) {
// Enable focus outlines so we can test them
React.useEffect(() => {
initFocusOutline();
}, []);
// Simulate navigation
const [currentPath, setCurrentPath] = React.useState('/admin/');

Wyświetl plik

@ -1,6 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Icon, Portal, initFocusOutline, initUpgradeNotification } from '../..';
import { Icon, Portal, initUpgradeNotification } from '../..';
if (process.env.NODE_ENV === 'development') {
// Run react-axe in development only, so it does not affect performance
@ -20,6 +20,5 @@ window.wagtail.components = {
* Add in here code to run once the page is loaded.
*/
document.addEventListener('DOMContentLoaded', () => {
initFocusOutline();
initUpgradeNotification();
});

Wyświetl plik

@ -9,7 +9,6 @@ import LoadingSpinner from './components/LoadingSpinner/LoadingSpinner';
import Portal from './components/Portal/Portal';
import PublicationStatus from './components/PublicationStatus/PublicationStatus';
import Transition from './components/Transition/Transition';
import { initFocusOutline } from './utils/focus';
import { initUpgradeNotification } from './components/UpgradeNotification';
export {
@ -19,6 +18,5 @@ export {
Portal,
PublicationStatus,
Transition,
initFocusOutline,
initUpgradeNotification,
};

Wyświetl plik

@ -1,30 +0,0 @@
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();
}
});
};

Wyświetl plik

@ -1,48 +0,0 @@
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');
});
});

Wyświetl plik

@ -39,6 +39,7 @@ The panel types `StreamFieldPanel`, `RichTextFieldPanel`, `ImageChooserPanel`, `
* Adopt [MyST](https://myst-parser.readthedocs.io/en/latest/) for parsing documentation written in Markdown, replaces recommonmark (LB (Ben Johnston), Thibaud Colas)
* Installing docs extras requirements in CircleCI so issues with the docs requirements are picked up earlier (Thibaud Colas)
* Remove core usage of jinjalint and migrate to curlylint to resolve dependency incompatibility issues (Thibaud Colas)
* Switch focus outlines implementation to `:focus-visible` for cross-browser consistency (Paarth Agarwal)
### Bug fixes