feat: use :focus-visible, add setting to enable/disable it (#1775)

* feat: use :focus-visible, add setting to enable it

* add the ids back

* css cleanup
This commit is contained in:
Nolan Lawson 2020-05-16 13:36:08 -07:00 committed by GitHub
parent 836b0e341f
commit cc62000b21
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 73 additions and 4 deletions

View file

@ -72,6 +72,7 @@
"file-api": "^0.10.4",
"file-drop-element": "0.2.0",
"file-loader": "^6.0.0",
"focus-visible": "^5.1.0",
"form-data": "^3.0.0",
"glob": "^7.1.6",
"indexeddb-getall-shim": "^1.3.6",

View file

@ -28,6 +28,25 @@
}
</style>
<style id="theFocusVisibleStyle" media="all">
/* :focus-visible styles */
/* polyfill */
.js-focus-visible :focus:not(.focus-visible) {
outline: none !important; /* important to win the specificity war */
}
.js-focus-visible :focus:not(.focus-visible).focus-after::after {
display: none;
}
/* standard version */
:focus:not(:focus-visible) {
outline: none !important; /* important to win the specificity war */
}
:focus:not(:focus-visible).focus-after::after {
display: none;
}
</style>
<noscript>
<style>
.hidden-from-ssr {

View file

@ -68,6 +68,18 @@
bind:checked="$reduceMotion" on:change="onChange(event)">
Reduce motion in UI animations
</label>
<label class="setting-group">
<input type="checkbox" id="choice-always-show-focus-ring"
bind:checked="$alwaysShowFocusRing" on:change="onChange(event)">
Always show
<Tooltip
text="focus ring"
tooltipText={
"The focus ring is the outline showing the currently focused element. By default, it's only " +
"shown when using the keyboard (not mouse or touch), but you may choose to always show it."
}
/>
</label>
<label class="setting-group">
<input type="checkbox" id="choice-disable-tap-on-status"
bind:checked="$disableTapOnStatus" on:change="onChange(event)">

View file

@ -0,0 +1,11 @@
const style = process.browser && document.getElementById('theFocusVisibleStyle')
export function focusRingObservers (store) {
if (!process.browser) {
return
}
store.observe('alwaysShowFocusRing', alwaysShowFocusRing => {
style.setAttribute('media', alwaysShowFocusRing ? 'only x' : 'all') // disable or enable the style
})
}

View file

@ -7,6 +7,7 @@ import { setupLoggedInObservers } from './setupLoggedInObservers'
import { logOutObservers } from './logOutObservers'
import { touchObservers } from './touchObservers'
import { grayscaleObservers } from './grayscaleObservers'
import { focusRingObservers } from './focusRingObservers'
import { leftRightFocusObservers } from './leftRightFocusObservers'
export function observers (store) {
@ -17,6 +18,7 @@ export function observers (store) {
resizeObservers(store)
touchObservers(store)
logOutObservers(store)
focusRingObservers(store)
grayscaleObservers(store)
leftRightFocusObservers(store)
setupLoggedInObservers(store)

View file

@ -6,6 +6,7 @@ import { observe } from 'svelte-extras'
import { isKaiOS } from '../_utils/userAgent/isKaiOS'
const persistedState = {
alwaysShowFocusRing: false,
autoplayGifs: false,
composeData: {},
currentInstance: null,

View file

@ -17,3 +17,7 @@ export const importCustomElementsPolyfill = () => import(
export const importIntl = () => import(
/* webpackChunkName: '$polyfill$-intl' */ 'intl'
)
export const importFocusVisible = () => import(
/* webpackChunkName: '$polyfill$-focus-visible' */ 'focus-visible'
)

View file

@ -1,10 +1,12 @@
import {
importCustomElementsPolyfill,
importFocusVisible,
importIndexedDBGetAllShim,
importIntersectionObserver,
importIntl,
importRequestIdleCallback
} from './asyncPolyfills'
import { supportsSelector } from './supportsSelector'
export function loadPolyfills () {
return Promise.all([
@ -12,6 +14,7 @@ export function loadPolyfills () {
typeof requestIdleCallback === 'undefined' && importRequestIdleCallback(),
!IDBObjectStore.prototype.getAll && importIndexedDBGetAllShim(),
typeof customElements === 'undefined' && importCustomElementsPolyfill(),
process.env.LEGACY && typeof Intl === 'undefined' && importIntl()
process.env.LEGACY && typeof Intl === 'undefined' && importIntl(),
!supportsSelector(':focus-visible') && importFocusVisible()
])
}

View file

@ -0,0 +1,13 @@
// See https://stackoverflow.com/a/8533927
export function supportsSelector (selector) {
const style = document.createElement('style')
document.head.appendChild(style)
try {
style.sheet.insertRule(selector + '{}', 0)
} catch (e) {
return false
} finally {
document.head.removeChild(style)
}
return true
}

View file

@ -1,6 +1,4 @@
*:focus {
:focus {
outline: var(--focus-width) solid var(--focus-outline);
}

View file

@ -4254,6 +4254,11 @@ flush-write-stream@^1.0.0:
inherits "^2.0.3"
readable-stream "^2.3.6"
focus-visible@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/focus-visible/-/focus-visible-5.1.0.tgz#4b9d40143b865f53eafbd93ca66672b3bf9e7b6a"
integrity sha512-nPer0rjtzdZ7csVIu233P2cUm/ks/4aVSI+5KUkYrYpgA7ujgC3p6J7FtFU+AIMWwnwYQOB/yeiOITxFeYIXiw==
for-in@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"