kopia lustrzana https://github.com/shoelace-style/shoelace
Fix `tabbable` performance issues in Chrome / Edge (#1614)
* fix: improve tabbable performance * add note about composed-offset-position * update package.json * prettier * prettier * prettierpull/1655/head
rodzic
ff94ea2e0c
commit
2643e4ff9e
20
package.json
20
package.json
|
@ -25,8 +25,15 @@
|
||||||
"./dist/react/*": "./dist/react/*",
|
"./dist/react/*": "./dist/react/*",
|
||||||
"./dist/translations/*": "./dist/translations/*"
|
"./dist/translations/*": "./dist/translations/*"
|
||||||
},
|
},
|
||||||
"files": ["dist", "cdn"],
|
"files": [
|
||||||
"keywords": ["web components", "custom elements", "components"],
|
"dist",
|
||||||
|
"cdn"
|
||||||
|
],
|
||||||
|
"keywords": [
|
||||||
|
"web components",
|
||||||
|
"custom elements",
|
||||||
|
"components"
|
||||||
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/shoelace-style/shoelace.git"
|
"url": "git+https://github.com/shoelace-style/shoelace.git"
|
||||||
|
@ -43,8 +50,8 @@
|
||||||
"build": "node scripts/build.js",
|
"build": "node scripts/build.js",
|
||||||
"verify": "npm run prettier:check && npm run lint && npm run build && npm run test",
|
"verify": "npm run prettier:check && npm run lint && npm run build && npm run test",
|
||||||
"prepublishOnly": "npm run verify",
|
"prepublishOnly": "npm run verify",
|
||||||
"prettier": "prettier --write --loglevel warn .",
|
"prettier": "prettier --write --log-level=warn .",
|
||||||
"prettier:check": "prettier --check --loglevel warn .",
|
"prettier:check": "prettier --check --log-level=warn .",
|
||||||
"lint": "eslint src --max-warnings 0",
|
"lint": "eslint src --max-warnings 0",
|
||||||
"lint:fix": "eslint src --max-warnings 0 --fix",
|
"lint:fix": "eslint src --max-warnings 0 --fix",
|
||||||
"ts-check": "tsc --noEmit --project ./tsconfig.json",
|
"ts-check": "tsc --noEmit --project ./tsconfig.json",
|
||||||
|
@ -133,6 +140,9 @@
|
||||||
"user-agent-data-types": "^0.3.1"
|
"user-agent-data-types": "^0.3.1"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.{ts,js}": ["eslint --max-warnings 0 --cache --fix", "prettier --write"]
|
"*.{ts,js}": [
|
||||||
|
"eslint --max-warnings 0 --cache --fix",
|
||||||
|
"prettier --write"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ export default class Modal {
|
||||||
|
|
||||||
if (currentFocusIndex === -1) {
|
if (currentFocusIndex === -1) {
|
||||||
this.currentFocus = tabbableElements[0];
|
this.currentFocus = tabbableElements[0];
|
||||||
this.currentFocus.focus({ preventScroll: true });
|
this.currentFocus?.focus({ preventScroll: true });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
import { offsetParent } from 'composed-offset-position';
|
// It doesn't technically check visibility, it checks if the element has been rendered and can maybe possibly be tabbed to.
|
||||||
|
// This is a workaround for shadowroots not having an `offsetParent`
|
||||||
|
// https://stackoverflow.com/questions/19669786/check-if-element-is-visible-in-dom
|
||||||
|
// Previously, we used https://www.npmjs.com/package/composed-offset-position, but recursing up an entire
|
||||||
|
// node tree took up a lot of CPU cycles and made focus traps unusable in Chrome / Edge.
|
||||||
|
function isTakingUpSpace(elem: HTMLElement): boolean {
|
||||||
|
return Boolean(elem.offsetParent || elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
|
||||||
|
}
|
||||||
/** Determines if the specified element is tabbable using heuristics inspired by https://github.com/focus-trap/tabbable */
|
/** Determines if the specified element is tabbable using heuristics inspired by https://github.com/focus-trap/tabbable */
|
||||||
function isTabbable(el: HTMLElement) {
|
function isTabbable(el: HTMLElement) {
|
||||||
const tag = el.tagName.toLowerCase();
|
const tag = el.tagName.toLowerCase();
|
||||||
|
@ -20,8 +26,8 @@ function isTabbable(el: HTMLElement) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Elements that are hidden have no offsetParent and are not tabbable
|
// Elements that are hidden have no offsetParent and are not tabbable
|
||||||
// offsetParent() is added because otherwise it misses elements in Safari
|
// !isRendered is added because otherwise it misses elements in Safari
|
||||||
if (el.offsetParent === null && offsetParent(el) === null) {
|
if (!isTakingUpSpace(el)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue