eslint: enable one-liner functions, dangling promises

pull/647/head
Jason O'Neill 2022-01-16 20:44:10 -08:00
rodzic 837dac17ea
commit 0330498bbb
52 zmienionych plików z 258 dodań i 273 usunięć

Wyświetl plik

@ -49,6 +49,13 @@ module.exports = {
'@typescript-eslint/no-unused-expressions': 'error', '@typescript-eslint/no-unused-expressions': 'error',
'@typescript-eslint/unbound-method': 'off', '@typescript-eslint/unbound-method': 'off',
'@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-floating-promises': 'off',
'@typescript-eslint/no-misused-promises': [
'error',
{
checksVoidReturn: false
}
],
'@typescript-eslint/consistent-type-assertions': [ '@typescript-eslint/consistent-type-assertions': [
'warn', 'warn',
{ {
@ -57,6 +64,7 @@ module.exports = {
} }
], ],
'@typescript-eslint/consistent-type-imports': 'warn', '@typescript-eslint/consistent-type-imports': 'warn',
// These are commented out for now as we may want to add them to improve function boundary safety
// "@typescript-eslint/explicit-function-return-type": [ // "@typescript-eslint/explicit-function-return-type": [
// "error", // "error",
// { // {
@ -67,7 +75,6 @@ module.exports = {
// "@typescript-eslint/explicit-module-boundary-types": "error", // "@typescript-eslint/explicit-module-boundary-types": "error",
'@typescript-eslint/no-base-to-string': 'error', '@typescript-eslint/no-base-to-string': 'error',
'@typescript-eslint/no-confusing-non-null-assertion': 'error', '@typescript-eslint/no-confusing-non-null-assertion': 'error',
'@typescript-eslint/no-confusing-void-expression': 'error',
'@typescript-eslint/no-invalid-void-type': 'error', '@typescript-eslint/no-invalid-void-type': 'error',
'@typescript-eslint/no-require-imports': 'error', '@typescript-eslint/no-require-imports': 'error',
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'warn', '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'warn',
@ -108,6 +115,10 @@ module.exports = {
{ {
selector: 'typeProperty', selector: 'typeProperty',
format: ['camelCase', 'PascalCase', 'UPPER_CASE'] format: ['camelCase', 'PascalCase', 'UPPER_CASE']
},
{
selector: 'objectLiteralProperty',
format: null
} }
], ],
'@typescript-eslint/no-extraneous-class': 'error', '@typescript-eslint/no-extraneous-class': 'error',

Wyświetl plik

@ -4,10 +4,8 @@ import { pascalCase } from 'pascal-case';
const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8')); const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
const { name, description, version, author, homepage, license } = packageData; const { name, description, version, author, homepage, license } = packageData;
// eslint-disable-next-line func-style
function noDash(string) { const noDash = string => string.replace(/^\s?-/, '').trim();
return string.replace(/^\s?-/, '').trim();
}
export default { export default {
globs: ['src/components/**/*.ts'], globs: ['src/components/**/*.ts'],

102
package-lock.json wygenerowano
Wyświetl plik

@ -15,7 +15,6 @@
"@shoelace-style/localize": "^2.1.3", "@shoelace-style/localize": "^2.1.3",
"color": "4.1", "color": "4.1",
"lit": "^2.1.0", "lit": "^2.1.0",
"lit-html": "^2.1.1",
"qr-creator": "^1.0.0" "qr-creator": "^1.0.0"
}, },
"devDependencies": { "devDependencies": {
@ -24,8 +23,8 @@
"@types/color": "^3.0.2", "@types/color": "^3.0.2",
"@types/mocha": "^9.0.0", "@types/mocha": "^9.0.0",
"@types/react": "^17.0.38", "@types/react": "^17.0.38",
"@typescript-eslint/eslint-plugin": "^5.9.0", "@typescript-eslint/eslint-plugin": "^5.9.1",
"@typescript-eslint/parser": "^5.9.0", "@typescript-eslint/parser": "^5.9.1",
"@web/dev-server-esbuild": "^0.2.16", "@web/dev-server-esbuild": "^0.2.16",
"@web/test-runner": "^0.13.23", "@web/test-runner": "^0.13.23",
"@web/test-runner-playwright": "^0.8.8", "@web/test-runner-playwright": "^0.8.8",
@ -38,7 +37,7 @@
"del": "^6.0.0", "del": "^6.0.0",
"download": "^8.0.0", "download": "^8.0.0",
"esbuild": "^0.14.10", "esbuild": "^0.14.10",
"eslint": "^8.6.0", "eslint": "8.6.0",
"eslint-plugin-chai-expect": "^3.0.0", "eslint-plugin-chai-expect": "^3.0.0",
"eslint-plugin-chai-friendly": "^0.7.2", "eslint-plugin-chai-friendly": "^0.7.2",
"eslint-plugin-import": "^2.25.4", "eslint-plugin-import": "^2.25.4",
@ -60,8 +59,7 @@
"sinon": "^12.0.1", "sinon": "^12.0.1",
"strip-css-comments": "^5.0.0", "strip-css-comments": "^5.0.0",
"tslib": "^2.3.1", "tslib": "^2.3.1",
"typescript": "^4.5.4", "typescript": "^4.5.4"
"utility-types": "^3.10.0"
}, },
"engines": { "engines": {
"node": ">=14.15.0" "node": ">=14.15.0"
@ -2337,6 +2335,15 @@
"string-width": "^4.1.0" "string-width": "^4.1.0"
} }
}, },
"node_modules/ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/ansi-escapes": { "node_modules/ansi-escapes": {
"version": "4.3.2", "version": "4.3.2",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
@ -5136,6 +5143,18 @@
} }
} }
}, },
"node_modules/enquirer": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
"integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
"dev": true,
"dependencies": {
"ansi-colors": "^4.1.1"
},
"engines": {
"node": ">=8.6"
}
},
"node_modules/env-paths": { "node_modules/env-paths": {
"version": "2.2.1", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
@ -5536,9 +5555,9 @@
} }
}, },
"node_modules/eslint": { "node_modules/eslint": {
"version": "8.7.0", "version": "8.6.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.7.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.6.0.tgz",
"integrity": "sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w==", "integrity": "sha512-UvxdOJ7mXFlw7iuHZA4jmzPaUqIw54mZrv+XPYKNbKdLR0et4rf60lIZUU9kiNtnzzMzGWxMV+tQ7uG7JG8DPw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@eslint/eslintrc": "^1.0.5", "@eslint/eslintrc": "^1.0.5",
@ -5548,10 +5567,11 @@
"cross-spawn": "^7.0.2", "cross-spawn": "^7.0.2",
"debug": "^4.3.2", "debug": "^4.3.2",
"doctrine": "^3.0.0", "doctrine": "^3.0.0",
"enquirer": "^2.3.5",
"escape-string-regexp": "^4.0.0", "escape-string-regexp": "^4.0.0",
"eslint-scope": "^7.1.0", "eslint-scope": "^7.1.0",
"eslint-utils": "^3.0.0", "eslint-utils": "^3.0.0",
"eslint-visitor-keys": "^3.2.0", "eslint-visitor-keys": "^3.1.0",
"espree": "^9.3.0", "espree": "^9.3.0",
"esquery": "^1.4.0", "esquery": "^1.4.0",
"esutils": "^2.0.2", "esutils": "^2.0.2",
@ -5560,7 +5580,7 @@
"functional-red-black-tree": "^1.0.1", "functional-red-black-tree": "^1.0.1",
"glob-parent": "^6.0.1", "glob-parent": "^6.0.1",
"globals": "^13.6.0", "globals": "^13.6.0",
"ignore": "^5.2.0", "ignore": "^4.0.6",
"import-fresh": "^3.0.0", "import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4", "imurmurhash": "^0.1.4",
"is-glob": "^4.0.0", "is-glob": "^4.0.0",
@ -5571,7 +5591,9 @@
"minimatch": "^3.0.4", "minimatch": "^3.0.4",
"natural-compare": "^1.4.0", "natural-compare": "^1.4.0",
"optionator": "^0.9.1", "optionator": "^0.9.1",
"progress": "^2.0.0",
"regexpp": "^3.2.0", "regexpp": "^3.2.0",
"semver": "^7.2.1",
"strip-ansi": "^6.0.1", "strip-ansi": "^6.0.1",
"strip-json-comments": "^3.1.0", "strip-json-comments": "^3.1.0",
"text-table": "^0.2.0", "text-table": "^0.2.0",
@ -5960,6 +5982,15 @@
"node": ">=10.13.0" "node": ">=10.13.0"
} }
}, },
"node_modules/eslint/node_modules/ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/eslint/node_modules/js-yaml": { "node_modules/eslint/node_modules/js-yaml": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@ -13567,15 +13598,6 @@
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"dev": true "dev": true
}, },
"node_modules/utility-types": {
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz",
"integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/utils-merge": { "node_modules/utils-merge": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@ -15920,6 +15942,12 @@
"string-width": "^4.1.0" "string-width": "^4.1.0"
} }
}, },
"ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
"dev": true
},
"ansi-escapes": { "ansi-escapes": {
"version": "4.3.2", "version": "4.3.2",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
@ -18080,6 +18108,15 @@
"has-binary2": "~1.0.2" "has-binary2": "~1.0.2"
} }
}, },
"enquirer": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
"integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
"dev": true,
"requires": {
"ansi-colors": "^4.1.1"
}
},
"env-paths": { "env-paths": {
"version": "2.2.1", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
@ -18338,9 +18375,9 @@
"dev": true "dev": true
}, },
"eslint": { "eslint": {
"version": "8.7.0", "version": "8.6.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.7.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.6.0.tgz",
"integrity": "sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w==", "integrity": "sha512-UvxdOJ7mXFlw7iuHZA4jmzPaUqIw54mZrv+XPYKNbKdLR0et4rf60lIZUU9kiNtnzzMzGWxMV+tQ7uG7JG8DPw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@eslint/eslintrc": "^1.0.5", "@eslint/eslintrc": "^1.0.5",
@ -18350,10 +18387,11 @@
"cross-spawn": "^7.0.2", "cross-spawn": "^7.0.2",
"debug": "^4.3.2", "debug": "^4.3.2",
"doctrine": "^3.0.0", "doctrine": "^3.0.0",
"enquirer": "^2.3.5",
"escape-string-regexp": "^4.0.0", "escape-string-regexp": "^4.0.0",
"eslint-scope": "^7.1.0", "eslint-scope": "^7.1.0",
"eslint-utils": "^3.0.0", "eslint-utils": "^3.0.0",
"eslint-visitor-keys": "^3.2.0", "eslint-visitor-keys": "^3.1.0",
"espree": "^9.3.0", "espree": "^9.3.0",
"esquery": "^1.4.0", "esquery": "^1.4.0",
"esutils": "^2.0.2", "esutils": "^2.0.2",
@ -18362,7 +18400,7 @@
"functional-red-black-tree": "^1.0.1", "functional-red-black-tree": "^1.0.1",
"glob-parent": "^6.0.1", "glob-parent": "^6.0.1",
"globals": "^13.6.0", "globals": "^13.6.0",
"ignore": "^5.2.0", "ignore": "^4.0.6",
"import-fresh": "^3.0.0", "import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4", "imurmurhash": "^0.1.4",
"is-glob": "^4.0.0", "is-glob": "^4.0.0",
@ -18373,7 +18411,9 @@
"minimatch": "^3.0.4", "minimatch": "^3.0.4",
"natural-compare": "^1.4.0", "natural-compare": "^1.4.0",
"optionator": "^0.9.1", "optionator": "^0.9.1",
"progress": "^2.0.0",
"regexpp": "^3.2.0", "regexpp": "^3.2.0",
"semver": "^7.2.1",
"strip-ansi": "^6.0.1", "strip-ansi": "^6.0.1",
"strip-json-comments": "^3.1.0", "strip-json-comments": "^3.1.0",
"text-table": "^0.2.0", "text-table": "^0.2.0",
@ -18430,6 +18470,12 @@
"is-glob": "^4.0.3" "is-glob": "^4.0.3"
} }
}, },
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
"dev": true
},
"js-yaml": { "js-yaml": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@ -24522,12 +24568,6 @@
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"dev": true "dev": true
}, },
"utility-types": {
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz",
"integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==",
"dev": true
},
"utils-merge": { "utils-merge": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",

Wyświetl plik

@ -56,7 +56,6 @@
"@shoelace-style/localize": "^2.1.3", "@shoelace-style/localize": "^2.1.3",
"color": "4.1", "color": "4.1",
"lit": "^2.1.0", "lit": "^2.1.0",
"lit-html": "^2.1.1",
"qr-creator": "^1.0.0" "qr-creator": "^1.0.0"
}, },
"devDependencies": { "devDependencies": {
@ -65,8 +64,8 @@
"@types/color": "^3.0.2", "@types/color": "^3.0.2",
"@types/mocha": "^9.0.0", "@types/mocha": "^9.0.0",
"@types/react": "^17.0.38", "@types/react": "^17.0.38",
"@typescript-eslint/eslint-plugin": "^5.9.0", "@typescript-eslint/eslint-plugin": "^5.9.1",
"@typescript-eslint/parser": "^5.9.0", "@typescript-eslint/parser": "^5.9.1",
"@web/dev-server-esbuild": "^0.2.16", "@web/dev-server-esbuild": "^0.2.16",
"@web/test-runner": "^0.13.23", "@web/test-runner": "^0.13.23",
"@web/test-runner-playwright": "^0.8.8", "@web/test-runner-playwright": "^0.8.8",
@ -79,7 +78,7 @@
"del": "^6.0.0", "del": "^6.0.0",
"download": "^8.0.0", "download": "^8.0.0",
"esbuild": "^0.14.10", "esbuild": "^0.14.10",
"eslint": "^8.6.0", "eslint": "8.6.0",
"eslint-plugin-chai-expect": "^3.0.0", "eslint-plugin-chai-expect": "^3.0.0",
"eslint-plugin-chai-friendly": "^0.7.2", "eslint-plugin-chai-friendly": "^0.7.2",
"eslint-plugin-import": "^2.25.4", "eslint-plugin-import": "^2.25.4",
@ -101,7 +100,6 @@
"sinon": "^12.0.1", "sinon": "^12.0.1",
"strip-css-comments": "^5.0.0", "strip-css-comments": "^5.0.0",
"tslib": "^2.3.1", "tslib": "^2.3.1",
"typescript": "^4.5.4", "typescript": "^4.5.4"
"utility-types": "^3.10.0"
} }
} }

Wyświetl plik

@ -25,7 +25,7 @@ describe('<sl-alert>', () => {
el.addEventListener('sl-show', showHandler); el.addEventListener('sl-show', showHandler);
el.addEventListener('sl-after-show', afterShowHandler); el.addEventListener('sl-after-show', afterShowHandler);
void el.show(); el.show();
await waitUntil(() => showHandler.calledOnce); await waitUntil(() => showHandler.calledOnce);
await waitUntil(() => afterShowHandler.calledOnce); await waitUntil(() => afterShowHandler.calledOnce);
@ -43,7 +43,7 @@ describe('<sl-alert>', () => {
el.addEventListener('sl-hide', hideHandler); el.addEventListener('sl-hide', hideHandler);
el.addEventListener('sl-after-hide', afterHideHandler); el.addEventListener('sl-after-hide', afterHideHandler);
void el.hide(); el.hide();
await waitUntil(() => hideHandler.calledOnce); await waitUntil(() => hideHandler.calledOnce);
await waitUntil(() => afterHideHandler.calledOnce); await waitUntil(() => afterHideHandler.calledOnce);

Wyświetl plik

@ -39,7 +39,7 @@ const toastStack = Object.assign(document.createElement('div'), { className: 'sl
export default class SlAlert extends LitElement { export default class SlAlert extends LitElement {
static styles = styles; static styles = styles;
private autoHideTimeout: NodeJS.Timeout; private autoHideTimeout: number;
@query('[part="base"]') base: HTMLElement; @query('[part="base"]') base: HTMLElement;
@ -99,7 +99,7 @@ export default class SlAlert extends LitElement {
requestAnimationFrame(() => { requestAnimationFrame(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- force a reflow for the initial transition // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- force a reflow for the initial transition
this.clientWidth; this.clientWidth;
void this.show(); this.show();
}); });
this.addEventListener( this.addEventListener(
@ -121,14 +121,12 @@ export default class SlAlert extends LitElement {
restartAutoHide() { restartAutoHide() {
clearTimeout(this.autoHideTimeout); clearTimeout(this.autoHideTimeout);
if (this.open && this.duration < Infinity) { if (this.open && this.duration < Infinity) {
this.autoHideTimeout = setTimeout(() => { this.autoHideTimeout = window.setTimeout(() => this.hide(), this.duration);
void this.hide();
}, this.duration);
} }
} }
handleCloseClick() { handleCloseClick() {
void this.hide(); this.hide();
} }
handleMouseMove() { handleMouseMove() {

Wyświetl plik

@ -84,7 +84,7 @@ export default class SlAnimation extends LitElement {
connectedCallback() { connectedCallback() {
super.connectedCallback(); super.connectedCallback();
void this.createAnimation(); this.createAnimation();
this.handleAnimationCancel = this.handleAnimationCancel.bind(this); this.handleAnimationCancel = this.handleAnimationCancel.bind(this);
this.handleAnimationFinish = this.handleAnimationFinish.bind(this); this.handleAnimationFinish = this.handleAnimationFinish.bind(this);
} }
@ -109,7 +109,7 @@ export default class SlAnimation extends LitElement {
return; return;
} }
void this.createAnimation(); this.createAnimation();
} }
handleAnimationFinish() { handleAnimationFinish() {
@ -152,7 +152,7 @@ export default class SlAnimation extends LitElement {
handleSlotChange() { handleSlotChange() {
this.destroyAnimation(); this.destroyAnimation();
void this.createAnimation(); this.createAnimation();
} }
async createAnimation() { async createAnimation() {

Wyświetl plik

@ -3,6 +3,7 @@ import { customElement, property, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js'; import { classMap } from 'lit/directives/class-map.js';
import styles from './avatar.styles'; import styles from './avatar.styles';
import '~/components/icon/icon'; import '~/components/icon/icon';
import { isTruthy } from '~/internal/is-truthy';
/** /**
* @since 2.0 * @since 2.0
@ -50,7 +51,7 @@ export default class SlAvatar extends LitElement {
role="img" role="img"
aria-label=${this.label} aria-label=${this.label}
> >
${typeof this.initials !== 'undefined' ${isTruthy(this.initials)
? html` <div part="initials" class="avatar__initials">${this.initials}</div> ` ? html` <div part="initials" class="avatar__initials">${this.initials}</div> `
: html` : html`
<div part="icon" class="avatar__icon" aria-hidden="true"> <div part="icon" class="avatar__icon" aria-hidden="true">
@ -59,7 +60,7 @@ export default class SlAvatar extends LitElement {
</slot> </slot>
</div> </div>
`} `}
${typeof this.image !== 'undefined' && !this.hasError ${typeof this.image === 'string' && !this.hasError
? html` ? html`
<img <img
part="image" part="image"

Wyświetl plik

@ -3,6 +3,7 @@ import { customElement, property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js'; import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined.js'; import { ifDefined } from 'lit/directives/if-defined.js';
import styles from './breadcrumb-item.styles'; import styles from './breadcrumb-item.styles';
import { isTruthy } from '~/internal/is-truthy';
import { HasSlotController } from '~/internal/slot'; import { HasSlotController } from '~/internal/slot';
/** /**
@ -62,7 +63,7 @@ export default class SlBreadcrumbItem extends LitElement {
class="breadcrumb-item__label breadcrumb-item__label--link" class="breadcrumb-item__label breadcrumb-item__label--link"
href="${this.href}" href="${this.href}"
target="${this.target}" target="${this.target}"
rel=${ifDefined(typeof this.target !== 'undefined' ? this.rel : undefined)} rel=${ifDefined(isTruthy(this.target) ? this.rel : undefined)}
> >
<slot></slot> <slot></slot>
</a> </a>

Wyświetl plik

@ -34,9 +34,7 @@ export default class SlBreadcrumb extends LitElement {
// Clone it, remove ids, and slot it // Clone it, remove ids, and slot it
const clone = separator.cloneNode(true) as HTMLElement; const clone = separator.cloneNode(true) as HTMLElement;
[clone, ...clone.querySelectorAll('[id]')].forEach(el => { [clone, ...clone.querySelectorAll('[id]')].forEach(el => el.removeAttribute('id'));
el.removeAttribute('id');
});
clone.slot = 'separator'; clone.slot = 'separator';
return clone; return clone;

Wyświetl plik

@ -56,7 +56,7 @@ export default class SlButtonGroup extends LitElement {
} }
render() { render() {
// eslint-disable-next-line lit-a11y/mouse-events-have-key-events -- focusout & focusin support bubbling where as focus & blur do not which is necessary here // eslint-disable-next-line lit-a11y/mouse-events-have-key-events -- focusout & focusin support bubbling whereas focus & blur do not which is necessary here
return html` return html`
<div <div
part="base" part="base"

Wyświetl plik

@ -7,6 +7,7 @@ import styles from './button.styles';
import '~/components/spinner/spinner'; import '~/components/spinner/spinner';
import { emit } from '~/internal/event'; import { emit } from '~/internal/event';
import { FormSubmitController } from '~/internal/form-control'; import { FormSubmitController } from '~/internal/form-control';
import { isTruthy } from '~/internal/is-truthy';
import { HasSlotController } from '~/internal/slot'; import { HasSlotController } from '~/internal/slot';
/** /**
@ -161,7 +162,7 @@ export default class SlButton extends LitElement {
href=${ifDefined(this.href)} href=${ifDefined(this.href)}
target=${ifDefined(this.target)} target=${ifDefined(this.target)}
download=${ifDefined(this.download)} download=${ifDefined(this.download)}
rel=${ifDefined(typeof this.target !== 'undefined' ? 'noreferrer noopener' : undefined)} rel=${ifDefined(isTruthy(this.target) ? 'noreferrer noopener' : undefined)}
role="button" role="button"
aria-disabled=${this.disabled ? 'true' : 'false'} aria-disabled=${this.disabled ? 'true' : 'false'}
tabindex=${this.disabled ? '-1' : '0'} tabindex=${this.disabled ? '-1' : '0'}

Wyświetl plik

@ -5,9 +5,9 @@ import type SlCheckbox from './checkbox';
describe('<sl-checkbox>', () => { describe('<sl-checkbox>', () => {
it('should be disabled with the disabled attribute', async () => { it('should be disabled with the disabled attribute', async () => {
const el = await fixture<SlCheckbox>(html` <sl-checkbox disabled></sl-checkbox> `); const el = await fixture<SlCheckbox>(html` <sl-checkbox disabled></sl-checkbox> `);
const checkbox = el.shadowRoot?.querySelector('input'); const checkbox = el.shadowRoot!.querySelector('input')!;
expect(checkbox!.disabled).to.be.true; expect(checkbox.disabled).to.be.true;
}); });
it('should be valid by default', async () => { it('should be valid by default', async () => {
@ -18,9 +18,7 @@ describe('<sl-checkbox>', () => {
it('should fire sl-change when clicked', async () => { it('should fire sl-change when clicked', async () => {
const el = await fixture<SlCheckbox>(html` <sl-checkbox></sl-checkbox> `); const el = await fixture<SlCheckbox>(html` <sl-checkbox></sl-checkbox> `);
setTimeout(() => { setTimeout(() => el.shadowRoot!.querySelector('input')!.click());
el.shadowRoot!.querySelector('input')!.click();
});
const event = await oneEvent(el, 'sl-change'); const event = await oneEvent(el, 'sl-change');
expect(event.target).to.equal(el); expect(event.target).to.equal(el);
expect(el.checked).to.be.true; expect(el.checked).to.be.true;
@ -30,9 +28,7 @@ describe('<sl-checkbox>', () => {
const el = await fixture<SlCheckbox>(html` <sl-checkbox></sl-checkbox> `); const el = await fixture<SlCheckbox>(html` <sl-checkbox></sl-checkbox> `);
const input = el.shadowRoot!.querySelector('input')!; const input = el.shadowRoot!.querySelector('input')!;
input.focus(); input.focus();
setTimeout(() => { setTimeout(() => sendKeys({ press: ' ' }));
void sendKeys({ press: ' ' });
});
const event = await oneEvent(el, 'sl-change'); const event = await oneEvent(el, 'sl-change');
expect(event.target).to.equal(el); expect(event.target).to.equal(el);
expect(el.checked).to.be.true; expect(el.checked).to.be.true;

Wyświetl plik

@ -4,7 +4,7 @@ import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined.js'; import { ifDefined } from 'lit/directives/if-defined.js';
import { live } from 'lit/directives/live.js'; import { live } from 'lit/directives/live.js';
import styles from './checkbox.styles'; import styles from './checkbox.styles';
import { autoIncrement } from '~/internal/autoIncrement'; import { autoIncrement } from '~/internal/auto-increment';
import { emit } from '~/internal/event'; import { emit } from '~/internal/event';
import { FormSubmitController } from '~/internal/form-control'; import { FormSubmitController } from '~/internal/form-control';
import { watch } from '~/internal/watch'; import { watch } from '~/internal/watch';

Wyświetl plik

@ -161,7 +161,7 @@ export default class SlColorPicker extends LitElement {
this.inputValue = this.value; this.inputValue = this.value;
this.lastValueEmitted = this.value; this.lastValueEmitted = this.value;
void this.syncValues(); this.syncValues();
} }
/** Returns the current value as a string in the specified format. */ /** Returns the current value as a string in the specified format. */
@ -205,7 +205,7 @@ export default class SlColorPicker extends LitElement {
}, },
{ once: true } { once: true }
); );
void this.dropdown.show(); this.dropdown.show();
}); });
} }
return this.input.reportValidity(); return this.input.reportValidity();
@ -245,7 +245,7 @@ export default class SlColorPicker extends LitElement {
drag(container, x => { drag(container, x => {
this.alpha = clamp((x / width) * 100, 0, 100); this.alpha = clamp((x / width) * 100, 0, 100);
void this.syncValues(); this.syncValues();
}); });
} }
@ -259,7 +259,7 @@ export default class SlColorPicker extends LitElement {
drag(container, x => { drag(container, x => {
this.hue = clamp((x / width) * 360, 0, 360); this.hue = clamp((x / width) * 360, 0, 360);
void this.syncValues(); this.syncValues();
}); });
} }
@ -274,7 +274,7 @@ export default class SlColorPicker extends LitElement {
drag(grid, (x, y) => { drag(grid, (x, y) => {
this.saturation = clamp((x / width) * 100, 0, 100); this.saturation = clamp((x / width) * 100, 0, 100);
this.lightness = clamp(100 - (y / height) * 100, 0, 100); this.lightness = clamp(100 - (y / height) * 100, 0, 100);
void this.syncValues(); this.syncValues();
}); });
} }
@ -284,25 +284,25 @@ export default class SlColorPicker extends LitElement {
if (event.key === 'ArrowLeft') { if (event.key === 'ArrowLeft') {
event.preventDefault(); event.preventDefault();
this.alpha = clamp(this.alpha - increment, 0, 100); this.alpha = clamp(this.alpha - increment, 0, 100);
void this.syncValues(); this.syncValues();
} }
if (event.key === 'ArrowRight') { if (event.key === 'ArrowRight') {
event.preventDefault(); event.preventDefault();
this.alpha = clamp(this.alpha + increment, 0, 100); this.alpha = clamp(this.alpha + increment, 0, 100);
void this.syncValues(); this.syncValues();
} }
if (event.key === 'Home') { if (event.key === 'Home') {
event.preventDefault(); event.preventDefault();
this.alpha = 0; this.alpha = 0;
void this.syncValues(); this.syncValues();
} }
if (event.key === 'End') { if (event.key === 'End') {
event.preventDefault(); event.preventDefault();
this.alpha = 100; this.alpha = 100;
void this.syncValues(); this.syncValues();
} }
} }
@ -312,25 +312,25 @@ export default class SlColorPicker extends LitElement {
if (event.key === 'ArrowLeft') { if (event.key === 'ArrowLeft') {
event.preventDefault(); event.preventDefault();
this.hue = clamp(this.hue - increment, 0, 360); this.hue = clamp(this.hue - increment, 0, 360);
void this.syncValues(); this.syncValues();
} }
if (event.key === 'ArrowRight') { if (event.key === 'ArrowRight') {
event.preventDefault(); event.preventDefault();
this.hue = clamp(this.hue + increment, 0, 360); this.hue = clamp(this.hue + increment, 0, 360);
void this.syncValues(); this.syncValues();
} }
if (event.key === 'Home') { if (event.key === 'Home') {
event.preventDefault(); event.preventDefault();
this.hue = 0; this.hue = 0;
void this.syncValues(); this.syncValues();
} }
if (event.key === 'End') { if (event.key === 'End') {
event.preventDefault(); event.preventDefault();
this.hue = 360; this.hue = 360;
void this.syncValues(); this.syncValues();
} }
} }
@ -340,25 +340,25 @@ export default class SlColorPicker extends LitElement {
if (event.key === 'ArrowLeft') { if (event.key === 'ArrowLeft') {
event.preventDefault(); event.preventDefault();
this.saturation = clamp(this.saturation - increment, 0, 100); this.saturation = clamp(this.saturation - increment, 0, 100);
void this.syncValues(); this.syncValues();
} }
if (event.key === 'ArrowRight') { if (event.key === 'ArrowRight') {
event.preventDefault(); event.preventDefault();
this.saturation = clamp(this.saturation + increment, 0, 100); this.saturation = clamp(this.saturation + increment, 0, 100);
void this.syncValues(); this.syncValues();
} }
if (event.key === 'ArrowUp') { if (event.key === 'ArrowUp') {
event.preventDefault(); event.preventDefault();
this.lightness = clamp(this.lightness + increment, 0, 100); this.lightness = clamp(this.lightness + increment, 0, 100);
void this.syncValues(); this.syncValues();
} }
if (event.key === 'ArrowDown') { if (event.key === 'ArrowDown') {
event.preventDefault(); event.preventDefault();
this.lightness = clamp(this.lightness - increment, 0, 100); this.lightness = clamp(this.lightness - increment, 0, 100);
void this.syncValues(); this.syncValues();
} }
} }
@ -374,9 +374,7 @@ export default class SlColorPicker extends LitElement {
if (event.key === 'Enter') { if (event.key === 'Enter') {
this.setColor(this.input.value); this.setColor(this.input.value);
this.input.value = this.value; this.input.value = this.value;
setTimeout(() => { setTimeout(() => this.input.select());
this.input.select();
});
} }
} }
@ -514,7 +512,7 @@ export default class SlColorPicker extends LitElement {
this.lightness = newColor.hsla.l; this.lightness = newColor.hsla.l;
this.alpha = this.opacity ? newColor.hsla.a * 100 : 100; this.alpha = this.opacity ? newColor.hsla.a * 100 : 100;
void this.syncValues(); this.syncValues();
return true; return true;
} }
@ -574,7 +572,7 @@ export default class SlColorPicker extends LitElement {
@watch('format') @watch('format')
handleFormatChange() { handleFormatChange() {
void this.syncValues(); this.syncValues();
} }
@watch('opacity') @watch('opacity')
@ -800,14 +798,12 @@ export default class SlColorPicker extends LitElement {
part="trigger" part="trigger"
slot="trigger" slot="trigger"
class=${classMap({ class=${classMap({
/* eslint-disable @typescript-eslint/naming-convention */
'color-dropdown__trigger': true, 'color-dropdown__trigger': true,
'color-dropdown__trigger--disabled': this.disabled, 'color-dropdown__trigger--disabled': this.disabled,
'color-dropdown__trigger--small': this.size === 'small', 'color-dropdown__trigger--small': this.size === 'small',
'color-dropdown__trigger--medium': this.size === 'medium', 'color-dropdown__trigger--medium': this.size === 'medium',
'color-dropdown__trigger--large': this.size === 'large', 'color-dropdown__trigger--large': this.size === 'large',
'color-picker__transparent-bg': true 'color-picker__transparent-bg': true
/* eslint-enable @typescript-eslint/naming-convention */
})} })}
style=${styleMap({ style=${styleMap({
color: `hsla(${this.hue}deg, ${this.saturation}%, ${this.lightness}%, ${this.alpha / 100})` color: `hsla(${this.hue}deg, ${this.saturation}%, ${this.lightness}%, ${this.alpha / 100})`

Wyświetl plik

@ -44,7 +44,7 @@ describe('<sl-details>', () => {
el.addEventListener('sl-show', showHandler); el.addEventListener('sl-show', showHandler);
el.addEventListener('sl-after-show', afterShowHandler); el.addEventListener('sl-after-show', afterShowHandler);
void el.show(); el.show();
await waitUntil(() => showHandler.calledOnce); await waitUntil(() => showHandler.calledOnce);
await waitUntil(() => afterShowHandler.calledOnce); await waitUntil(() => afterShowHandler.calledOnce);
@ -68,7 +68,7 @@ describe('<sl-details>', () => {
el.addEventListener('sl-hide', hideHandler); el.addEventListener('sl-hide', hideHandler);
el.addEventListener('sl-after-hide', afterHideHandler); el.addEventListener('sl-after-hide', afterHideHandler);
void el.hide(); el.hide();
await waitUntil(() => hideHandler.calledOnce); await waitUntil(() => hideHandler.calledOnce);
await waitUntil(() => afterHideHandler.calledOnce); await waitUntil(() => afterHideHandler.calledOnce);
@ -139,13 +139,13 @@ describe('<sl-details>', () => {
`); `);
const first = el.querySelectorAll('sl-details')[0]; const first = el.querySelectorAll('sl-details')[0];
const second = el.querySelectorAll('sl-details')[1]; const second = el.querySelectorAll('sl-details')[1];
const firstBody = first.shadowRoot?.querySelector('.details__body'); const firstBody = first.shadowRoot!.querySelector('.details__body')!;
const secondBody = second.shadowRoot?.querySelector('.details__body'); const secondBody = second.shadowRoot!.querySelector('.details__body')!;
await first.show(); await first.show();
await second.show(); await second.show();
expect(firstBody!.clientHeight).to.equal(200); expect(firstBody.clientHeight).to.equal(200);
expect(secondBody!.clientHeight).to.equal(400); expect(secondBody.clientHeight).to.equal(400);
}); });
}); });

Wyświetl plik

@ -75,9 +75,9 @@ export default class SlDetails extends LitElement {
toggleOpen() { toggleOpen() {
if (this.open) { if (this.open) {
void this.hide(); this.hide();
} else { } else {
void this.show(); this.show();
} }
} }
@ -96,12 +96,12 @@ export default class SlDetails extends LitElement {
if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') { if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {
event.preventDefault(); event.preventDefault();
void this.hide(); this.hide();
} }
if (event.key === 'ArrowDown' || event.key === 'ArrowRight') { if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {
event.preventDefault(); event.preventDefault();
void this.show(); this.show();
} }
} }

Wyświetl plik

@ -32,7 +32,7 @@ describe('<sl-dialog>', () => {
el.addEventListener('sl-show', showHandler); el.addEventListener('sl-show', showHandler);
el.addEventListener('sl-after-show', afterShowHandler); el.addEventListener('sl-after-show', afterShowHandler);
void el.show(); el.show();
await waitUntil(() => showHandler.calledOnce); await waitUntil(() => showHandler.calledOnce);
await waitUntil(() => afterShowHandler.calledOnce); await waitUntil(() => afterShowHandler.calledOnce);
@ -52,7 +52,7 @@ describe('<sl-dialog>', () => {
el.addEventListener('sl-hide', hideHandler); el.addEventListener('sl-hide', hideHandler);
el.addEventListener('sl-after-hide', afterHideHandler); el.addEventListener('sl-after-hide', afterHideHandler);
void el.hide(); el.hide();
await waitUntil(() => hideHandler.calledOnce); await waitUntil(() => hideHandler.calledOnce);
await waitUntil(() => afterHideHandler.calledOnce); await waitUntil(() => afterHideHandler.calledOnce);
@ -125,7 +125,7 @@ describe('<sl-dialog>', () => {
}); });
el.addEventListener('sl-initial-focus', initialFocusHandler); el.addEventListener('sl-initial-focus', initialFocusHandler);
void el.show(); el.show();
await waitUntil(() => initialFocusHandler.calledOnce); await waitUntil(() => initialFocusHandler.calledOnce);

Wyświetl plik

@ -125,11 +125,11 @@ export default class SlDialog extends LitElement {
const slRequestClose = emit(this, 'sl-request-close', { cancelable: true }); const slRequestClose = emit(this, 'sl-request-close', { cancelable: true });
if (slRequestClose.defaultPrevented) { if (slRequestClose.defaultPrevented) {
const animation = getAnimation(this, 'dialog.denyClose'); const animation = getAnimation(this, 'dialog.denyClose');
void animateTo(this.panel, animation.keyframes, animation.options); animateTo(this.panel, animation.keyframes, animation.options);
return; return;
} }
void this.hide(); this.hide();
} }
handleKeyDown(event: KeyboardEvent) { handleKeyDown(event: KeyboardEvent) {
@ -196,9 +196,7 @@ export default class SlDialog extends LitElement {
// Restore focus to the original trigger // Restore focus to the original trigger
const trigger = this.originalTrigger; const trigger = this.originalTrigger;
if (typeof trigger?.focus === 'function') { if (typeof trigger?.focus === 'function') {
setTimeout(() => { setTimeout(() => trigger.focus());
trigger.focus();
});
} }
emit(this, 'sl-after-hide'); emit(this, 'sl-after-hide');
@ -206,6 +204,7 @@ export default class SlDialog extends LitElement {
} }
render() { render() {
/* eslint-disable lit-a11y/click-events-have-key-events */
return html` return html`
<div <div
part="base" part="base"
@ -216,13 +215,7 @@ export default class SlDialog extends LitElement {
})} })}
@keydown=${this.handleKeyDown} @keydown=${this.handleKeyDown}
> >
<div <div part="overlay" class="dialog__overlay" @click=${this.requestClose} tabindex="-1"></div>
part="overlay"
class="dialog__overlay"
@click=${this.requestClose}
@keydown=${this.handleKeyDown}
tabindex="-1"
></div>
<div <div
part="panel" part="panel"
@ -261,6 +254,7 @@ export default class SlDialog extends LitElement {
</div> </div>
</div> </div>
`; `;
/* eslint-enable lit-a11y/click-events-have-key-events */
} }
} }

Wyświetl plik

@ -32,7 +32,7 @@ describe('<sl-drawer>', () => {
el.addEventListener('sl-show', showHandler); el.addEventListener('sl-show', showHandler);
el.addEventListener('sl-after-show', afterShowHandler); el.addEventListener('sl-after-show', afterShowHandler);
void el.show(); el.show();
await waitUntil(() => showHandler.calledOnce); await waitUntil(() => showHandler.calledOnce);
await waitUntil(() => afterShowHandler.calledOnce); await waitUntil(() => afterShowHandler.calledOnce);
@ -52,7 +52,7 @@ describe('<sl-drawer>', () => {
el.addEventListener('sl-hide', hideHandler); el.addEventListener('sl-hide', hideHandler);
el.addEventListener('sl-after-hide', afterHideHandler); el.addEventListener('sl-after-hide', afterHideHandler);
void el.hide(); el.hide();
await waitUntil(() => hideHandler.calledOnce); await waitUntil(() => hideHandler.calledOnce);
await waitUntil(() => afterHideHandler.calledOnce); await waitUntil(() => afterHideHandler.calledOnce);
@ -125,7 +125,7 @@ describe('<sl-drawer>', () => {
}); });
el.addEventListener('sl-initial-focus', initialFocusHandler); el.addEventListener('sl-initial-focus', initialFocusHandler);
void el.show(); el.show();
await waitUntil(() => initialFocusHandler.calledOnce); await waitUntil(() => initialFocusHandler.calledOnce);

Wyświetl plik

@ -142,11 +142,11 @@ export default class SlDrawer extends LitElement {
const slRequestClose = emit(this, 'sl-request-close', { cancelable: true }); const slRequestClose = emit(this, 'sl-request-close', { cancelable: true });
if (slRequestClose.defaultPrevented) { if (slRequestClose.defaultPrevented) {
const animation = getAnimation(this, 'drawer.denyClose'); const animation = getAnimation(this, 'drawer.denyClose');
void animateTo(this.panel, animation.keyframes, animation.options); animateTo(this.panel, animation.keyframes, animation.options);
return; return;
} }
void this.hide(); this.hide();
} }
handleKeyDown(event: KeyboardEvent) { handleKeyDown(event: KeyboardEvent) {
@ -216,9 +216,7 @@ export default class SlDrawer extends LitElement {
// Restore focus to the original trigger // Restore focus to the original trigger
const trigger = this.originalTrigger; const trigger = this.originalTrigger;
if (typeof trigger?.focus === 'function') { if (typeof trigger?.focus === 'function') {
setTimeout(() => { setTimeout(() => trigger.focus());
trigger.focus();
});
} }
emit(this, 'sl-after-hide'); emit(this, 'sl-after-hide');
@ -226,6 +224,7 @@ export default class SlDrawer extends LitElement {
} }
render() { render() {
/* eslint-disable lit-a11y/click-events-have-key-events */
return html` return html`
<div <div
part="base" part="base"
@ -242,13 +241,7 @@ export default class SlDrawer extends LitElement {
})} })}
@keydown=${this.handleKeyDown} @keydown=${this.handleKeyDown}
> >
<div <div part="overlay" class="drawer__overlay" @click=${this.requestClose} tabindex="-1"></div>
part="overlay"
class="drawer__overlay"
@click=${this.requestClose}
@keydown=${this.handleKeyDown}
tabindex="-1"
></div>
<div <div
part="panel" part="panel"
@ -288,6 +281,7 @@ export default class SlDrawer extends LitElement {
</div> </div>
</div> </div>
`; `;
/* eslint-enable lit-a11y/click-events-have-key-events */
} }
} }

Wyświetl plik

@ -52,7 +52,7 @@ describe('<sl-dropdown>', () => {
el.addEventListener('sl-show', showHandler); el.addEventListener('sl-show', showHandler);
el.addEventListener('sl-after-show', afterShowHandler); el.addEventListener('sl-after-show', afterShowHandler);
void el.show(); el.show();
await waitUntil(() => showHandler.calledOnce); await waitUntil(() => showHandler.calledOnce);
await waitUntil(() => afterShowHandler.calledOnce); await waitUntil(() => afterShowHandler.calledOnce);
@ -79,7 +79,7 @@ describe('<sl-dropdown>', () => {
el.addEventListener('sl-hide', hideHandler); el.addEventListener('sl-hide', hideHandler);
el.addEventListener('sl-after-hide', afterHideHandler); el.addEventListener('sl-after-hide', afterHideHandler);
void el.hide(); el.hide();
await waitUntil(() => hideHandler.calledOnce); await waitUntil(() => hideHandler.calledOnce);
await waitUntil(() => afterHideHandler.calledOnce); await waitUntil(() => afterHideHandler.calledOnce);

Wyświetl plik

@ -8,6 +8,7 @@ import type SlMenuItem from '~/components/menu-item/menu-item';
import type SlMenu from '~/components/menu/menu'; import type SlMenu from '~/components/menu/menu';
import { animateTo, stopAnimations } from '~/internal/animate'; import { animateTo, stopAnimations } from '~/internal/animate';
import { emit, waitForEvent } from '~/internal/event'; import { emit, waitForEvent } from '~/internal/event';
import { isTruthy } from '~/internal/is-truthy';
import { scrollIntoView } from '~/internal/scroll'; import { scrollIntoView } from '~/internal/scroll';
import { getTabbableBoundary } from '~/internal/tabbable'; import { getTabbableBoundary } from '~/internal/tabbable';
import { watch } from '~/internal/watch'; import { watch } from '~/internal/watch';
@ -99,7 +100,7 @@ export default class SlDropdown extends LitElement {
} }
// Create the popover after render // Create the popover after render
void this.updateComplete.then(() => { this.updateComplete.then(() => {
this.popover = createPopper(this.trigger, this.positioner, { this.popover = createPopper(this.trigger, this.positioner, {
placement: this.placement, placement: this.placement,
strategy: this.hoist ? 'fixed' : 'absolute', strategy: this.hoist ? 'fixed' : 'absolute',
@ -127,7 +128,7 @@ export default class SlDropdown extends LitElement {
disconnectedCallback() { disconnectedCallback() {
super.disconnectedCallback(); super.disconnectedCallback();
void void this.hide(); this.hide();
this.popover?.destroy(); this.popover?.destroy();
} }
@ -150,7 +151,7 @@ export default class SlDropdown extends LitElement {
handleDocumentKeyDown(event: KeyboardEvent) { handleDocumentKeyDown(event: KeyboardEvent) {
// Close when escape is pressed // Close when escape is pressed
if (event.key === 'Escape') { if (event.key === 'Escape') {
void this.hide(); this.hide();
this.focusOnTrigger(); this.focusOnTrigger();
return; return;
} }
@ -160,7 +161,7 @@ export default class SlDropdown extends LitElement {
// Tabbing within an open menu should close the dropdown and refocus the trigger // Tabbing within an open menu should close the dropdown and refocus the trigger
if (this.open && document.activeElement?.tagName.toLowerCase() === 'sl-menu-item') { if (this.open && document.activeElement?.tagName.toLowerCase() === 'sl-menu-item') {
event.preventDefault(); event.preventDefault();
void this.hide(); this.hide();
this.focusOnTrigger(); this.focusOnTrigger();
return; return;
} }
@ -176,10 +177,10 @@ export default class SlDropdown extends LitElement {
: document.activeElement; : document.activeElement;
if ( if (
typeof this.containingElement === 'undefined' || !isTruthy(this.containingElement) ||
activeElement?.closest(this.containingElement.tagName.toLowerCase()) !== this.containingElement activeElement?.closest(this.containingElement.tagName.toLowerCase()) !== this.containingElement
) { ) {
void this.hide(); this.hide();
} }
}); });
} }
@ -188,8 +189,8 @@ export default class SlDropdown extends LitElement {
handleDocumentMouseDown(event: MouseEvent) { handleDocumentMouseDown(event: MouseEvent) {
// Close when clicking outside of the containing element // Close when clicking outside of the containing element
const path = event.composedPath(); const path = event.composedPath();
if (typeof this.containingElement !== 'undefined' && !path.includes(this.containingElement)) { if (isTruthy(this.containingElement) && !path.includes(this.containingElement)) {
void this.hide(); this.hide();
} }
} }
@ -203,7 +204,7 @@ export default class SlDropdown extends LitElement {
// Hide the dropdown when a menu item is selected // Hide the dropdown when a menu item is selected
if (!this.stayOpenOnSelect && target.tagName.toLowerCase() === 'sl-menu') { if (!this.stayOpenOnSelect && target.tagName.toLowerCase() === 'sl-menu') {
void this.hide(); this.hide();
this.focusOnTrigger(); this.focusOnTrigger();
} }
} }
@ -213,7 +214,7 @@ export default class SlDropdown extends LitElement {
@watch('placement') @watch('placement')
@watch('skidding') @watch('skidding')
handlePopoverOptionsChange() { handlePopoverOptionsChange() {
void this.popover?.setOptions({ this.popover?.setOptions({
placement: this.placement, placement: this.placement,
strategy: this.hoist ? 'fixed' : 'absolute', strategy: this.hoist ? 'fixed' : 'absolute',
modifiers: [ modifiers: [
@ -235,22 +236,22 @@ export default class SlDropdown extends LitElement {
handleTriggerClick() { handleTriggerClick() {
if (this.open) { if (this.open) {
void this.hide(); this.hide();
} else { } else {
void this.show(); this.show();
} }
} }
handleTriggerKeyDown(event: KeyboardEvent) { handleTriggerKeyDown(event: KeyboardEvent) {
const menu = this.getMenu(); const menu = this.getMenu();
const menuItems = typeof menu !== 'undefined' ? ([...menu.querySelectorAll('sl-menu-item')] as SlMenuItem[]) : []; const menuItems = [...(menu?.querySelectorAll('sl-menu-item') ?? [])] as SlMenuItem[];
const firstMenuItem = menuItems[0]; const firstMenuItem = menuItems[0];
const lastMenuItem = menuItems[menuItems.length - 1]; const lastMenuItem = menuItems[menuItems.length - 1];
// Close when escape or tab is pressed // Close when escape or tab is pressed
if (event.key === 'Escape') { if (event.key === 'Escape') {
this.focusOnTrigger(); this.focusOnTrigger();
void this.hide(); this.hide();
return; return;
} }
@ -270,7 +271,7 @@ export default class SlDropdown extends LitElement {
// Show the menu if it's not already open // Show the menu if it's not already open
if (!this.open) { if (!this.open) {
void this.show(); this.show();
} }
// Focus on a menu item // Focus on a menu item
@ -355,7 +356,7 @@ export default class SlDropdown extends LitElement {
return; return;
} }
void this.popover?.update(); this.popover?.update();
} }
@watch('open', { waitUntilFirstUpdate: true }) @watch('open', { waitUntilFirstUpdate: true })
@ -375,7 +376,7 @@ export default class SlDropdown extends LitElement {
document.addEventListener('mousedown', this.handleDocumentMouseDown); document.addEventListener('mousedown', this.handleDocumentMouseDown);
await stopAnimations(this); await stopAnimations(this);
void this.popover?.update(); this.popover?.update();
this.panel.hidden = false; this.panel.hidden = false;
const { keyframes, options } = getAnimation(this, 'dropdown.show'); const { keyframes, options } = getAnimation(this, 'dropdown.show');
await animateTo(this.panel, keyframes, options); await animateTo(this.panel, keyframes, options);

Wyświetl plik

@ -4,6 +4,7 @@ import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined.js'; import { ifDefined } from 'lit/directives/if-defined.js';
import styles from './icon-button.styles'; import styles from './icon-button.styles';
import '~/components/icon/icon'; import '~/components/icon/icon';
import { isTruthy } from '~/internal/is-truthy';
/** /**
* @since 2.0 * @since 2.0
@ -66,7 +67,7 @@ export default class SlIconButton extends LitElement {
href=${ifDefined(this.href)} href=${ifDefined(this.href)}
target=${ifDefined(this.target)} target=${ifDefined(this.target)}
download=${ifDefined(this.download)} download=${ifDefined(this.download)}
rel=${ifDefined(typeof this.target !== 'undefined' ? 'noreferrer noopener' : undefined)} rel=${ifDefined(isTruthy(this.target) ? 'noreferrer noopener' : undefined)}
role="button" role="button"
aria-disabled=${this.disabled ? 'true' : 'false'} aria-disabled=${this.disabled ? 'true' : 'false'}
aria-label="${this.label}" aria-label="${this.label}"

Wyświetl plik

@ -47,7 +47,7 @@ export default class SlIcon extends LitElement {
} }
firstUpdated() { firstUpdated() {
void this.setIcon(); this.setIcon();
} }
disconnectedCallback() { disconnectedCallback() {
@ -65,7 +65,7 @@ export default class SlIcon extends LitElement {
/** @internal Fetches the icon and redraws it. Used to handle library registrations. */ /** @internal Fetches the icon and redraws it. Used to handle library registrations. */
redraw() { redraw() {
void this.setIcon(); this.setIcon();
} }
@watch('name') @watch('name')
@ -76,7 +76,7 @@ export default class SlIcon extends LitElement {
const url = this.getUrl(); const url = this.getUrl();
if (typeof url !== 'undefined' && url.length > 0) { if (typeof url !== 'undefined' && url.length > 0) {
try { try {
const file = await requestIcon(url)!; const file = await requestIcon(url);
if (url !== this.getUrl()) { if (url !== this.getUrl()) {
// If the url has changed while fetching the icon, ignore this request // If the url has changed while fetching the icon, ignore this request
return; return;
@ -107,7 +107,7 @@ export default class SlIcon extends LitElement {
} }
handleChange() { handleChange() {
void this.setIcon(); this.setIcon();
} }
render() { render() {

Wyświetl plik

@ -3,7 +3,7 @@ import { customElement, property, query } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js'; import { styleMap } from 'lit/directives/style-map.js';
import styles from './image-comparer.styles'; import styles from './image-comparer.styles';
import '~/components/icon/icon'; import '~/components/icon/icon';
import { autoIncrement } from '~/internal/autoIncrement'; import { autoIncrement } from '~/internal/auto-increment';
import { drag } from '~/internal/drag'; import { drag } from '~/internal/drag';
import { emit } from '~/internal/event'; import { emit } from '~/internal/event';
import { clamp } from '~/internal/math'; import { clamp } from '~/internal/math';

Wyświetl plik

@ -1,4 +1,4 @@
import { expect, fixture, html, waitUntil } from '@open-wc/testing'; import { expect, fixture, html, waitUntil, aTimeout } from '@open-wc/testing';
import sinon from 'sinon'; import sinon from 'sinon';
import type SlInclude from './include'; import type SlInclude from './include';
@ -20,12 +20,10 @@ const stubbedFetchResponse: Response = {
clone: sinon.fake() clone: sinon.fake()
}; };
function delayResolve(resolveValue: string) { async function delayResolve(resolveValue: string) {
return new Promise<string>(resolve => { // Delay the fetch response to give time for the event listener to attach
setTimeout(() => { await aTimeout(10);
resolve(resolveValue); return resolveValue;
});
});
} }
describe('<sl-include>', () => { describe('<sl-include>', () => {

Wyświetl plik

@ -35,9 +35,7 @@ export default class SlInclude extends LitElement {
executeScript(script: HTMLScriptElement) { executeScript(script: HTMLScriptElement) {
// Create a copy of the script and swap it out so the browser executes it // Create a copy of the script and swap it out so the browser executes it
const newScript = document.createElement('script'); const newScript = document.createElement('script');
[...script.attributes].forEach(attr => { [...script.attributes].forEach(attr => newScript.setAttribute(attr.name, attr.value));
newScript.setAttribute(attr.name, attr.value);
});
newScript.textContent = script.textContent; newScript.textContent = script.textContent;
script.parentNode!.replaceChild(newScript, script); script.parentNode!.replaceChild(newScript, script);
} }
@ -65,9 +63,7 @@ export default class SlInclude extends LitElement {
this.innerHTML = file.html; this.innerHTML = file.html;
if (this.allowScripts) { if (this.allowScripts) {
[...this.querySelectorAll('script')].forEach(script => { [...this.querySelectorAll('script')].forEach(script => this.executeScript(script));
this.executeScript(script);
});
} }
emit(this, 'sl-load'); emit(this, 'sl-load');

Wyświetl plik

@ -5,7 +5,7 @@ import { ifDefined } from 'lit/directives/if-defined.js';
import { live } from 'lit/directives/live.js'; import { live } from 'lit/directives/live.js';
import styles from './input.styles'; import styles from './input.styles';
import '~/components/icon/icon'; import '~/components/icon/icon';
import { autoIncrement } from '~/internal/autoIncrement'; import { autoIncrement } from '~/internal/auto-increment';
import { emit } from '~/internal/event'; import { emit } from '~/internal/event';
import { FormSubmitController, getLabelledBy, renderFormControl } from '~/internal/form-control'; import { FormSubmitController, getLabelledBy, renderFormControl } from '~/internal/form-control';
import { HasSlotController } from '~/internal/slot'; import { HasSlotController } from '~/internal/slot';

Wyświetl plik

@ -28,7 +28,7 @@ export default class SlMenu extends LitElement {
@query('slot') defaultSlot: HTMLSlotElement; @query('slot') defaultSlot: HTMLSlotElement;
private typeToSelectString = ''; private typeToSelectString = '';
private typeToSelectTimeout: NodeJS.Timeout; private typeToSelectTimeout: number;
firstUpdated() { firstUpdated() {
this.setAttribute('role', 'menu'); this.setAttribute('role', 'menu');
@ -79,14 +79,12 @@ export default class SlMenu extends LitElement {
typeToSelect(key: string) { typeToSelect(key: string) {
const items = this.getAllItems({ includeDisabled: false }); const items = this.getAllItems({ includeDisabled: false });
clearTimeout(this.typeToSelectTimeout); clearTimeout(this.typeToSelectTimeout);
this.typeToSelectTimeout = setTimeout(() => (this.typeToSelectString = ''), 750); this.typeToSelectTimeout = window.setTimeout(() => (this.typeToSelectString = ''), 750);
this.typeToSelectString += key.toLowerCase(); this.typeToSelectString += key.toLowerCase();
// Restore focus in browsers that don't support :focus-visible when using the keyboard // Restore focus in browsers that don't support :focus-visible when using the keyboard
if (!hasFocusVisible) { if (!hasFocusVisible) {
items.forEach(item => { items.forEach(item => item.classList.remove('sl-focus-invisible'));
item.classList.remove('sl-focus-invisible');
});
} }
for (const item of items) { for (const item of items) {

Wyświetl plik

@ -19,7 +19,7 @@ describe('<sl-radio>', () => {
it('should fire sl-change when clicked', async () => { it('should fire sl-change when clicked', async () => {
const el = await fixture<SlRadio>(html` <sl-radio></sl-radio> `); const el = await fixture<SlRadio>(html` <sl-radio></sl-radio> `);
setTimeout(() => el.shadowRoot?.querySelector('input')?.click()); setTimeout(() => el.shadowRoot!.querySelector('input')!.click());
const event = await oneEvent(el, 'sl-change'); const event = await oneEvent(el, 'sl-change');
expect(event.target).to.equal(el); expect(event.target).to.equal(el);
expect(el.checked).to.be.true; expect(el.checked).to.be.true;
@ -29,9 +29,7 @@ describe('<sl-radio>', () => {
const el = await fixture<SlRadio>(html` <sl-radio></sl-radio> `); const el = await fixture<SlRadio>(html` <sl-radio></sl-radio> `);
const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!; const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
input.focus(); input.focus();
setTimeout(() => { setTimeout(() => sendKeys({ press: ' ' }));
void sendKeys({ press: ' ' });
});
const event = await oneEvent(el, 'sl-change'); const event = await oneEvent(el, 'sl-change');
expect(event.target).to.equal(el); expect(event.target).to.equal(el);
expect(el.checked).to.be.true; expect(el.checked).to.be.true;
@ -48,9 +46,7 @@ describe('<sl-radio>', () => {
const radio2 = radioGroup.querySelector<SlRadio>('sl-radio#radio-2')!; const radio2 = radioGroup.querySelector<SlRadio>('sl-radio#radio-2')!;
const input1 = radio1.shadowRoot!.querySelector<HTMLInputElement>('input')!; const input1 = radio1.shadowRoot!.querySelector<HTMLInputElement>('input')!;
input1.focus(); input1.focus();
setTimeout(() => { setTimeout(() => sendKeys({ press: 'ArrowRight' }));
void sendKeys({ press: 'ArrowRight' });
});
const event = await oneEvent(radio2, 'sl-change'); const event = await oneEvent(radio2, 'sl-change');
expect(event.target).to.equal(radio2); expect(event.target).to.equal(radio2);
expect(radio2.checked).to.be.true; expect(radio2.checked).to.be.true;

Wyświetl plik

@ -55,10 +55,9 @@ export default class SlRadio extends LitElement {
@property({ type: Boolean, reflect: true }) invalid = false; @property({ type: Boolean, reflect: true }) invalid = false;
firstUpdated() { firstUpdated() {
const radios = this.getAllRadios(); this.updateComplete.then(() => {
const checkedRadio = radios.find(radio => radio.checked); const radios = this.getAllRadios();
const checkedRadio = radios.find(radio => radio.checked);
setTimeout(() => {
radios.forEach(radio => { radios.forEach(radio => {
radio.input.tabIndex = -1; radio.input.tabIndex = -1;
}); });

Wyświetl plik

@ -4,7 +4,7 @@ import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined.js'; import { ifDefined } from 'lit/directives/if-defined.js';
import { live } from 'lit/directives/live.js'; import { live } from 'lit/directives/live.js';
import styles from './range.styles'; import styles from './range.styles';
import { autoIncrement } from '~/internal/autoIncrement'; import { autoIncrement } from '~/internal/auto-increment';
import { emit } from '~/internal/event'; import { emit } from '~/internal/event';
import { FormSubmitController, getLabelledBy, renderFormControl } from '~/internal/form-control'; import { FormSubmitController, getLabelledBy, renderFormControl } from '~/internal/form-control';
import { HasSlotController } from '~/internal/slot'; import { HasSlotController } from '~/internal/slot';
@ -88,9 +88,7 @@ export default class SlRange extends LitElement {
connectedCallback() { connectedCallback() {
super.connectedCallback(); super.connectedCallback();
this.resizeObserver = new ResizeObserver(() => { this.resizeObserver = new ResizeObserver(() => this.syncRange());
this.syncRange();
});
if (typeof this.value === 'undefined') { if (typeof this.value === 'undefined') {
this.value = this.min; this.value = this.min;
@ -102,7 +100,7 @@ export default class SlRange extends LitElement {
this.value = this.max; this.value = this.max;
} }
void this.updateComplete.then(() => { this.updateComplete.then(() => {
this.syncRange(); this.syncRange();
this.resizeObserver.observe(this.input); this.resizeObserver.observe(this.input);
}); });

Wyświetl plik

@ -203,9 +203,7 @@ export default class SlRating extends LitElement {
return html` return html`
<span <span
class=${classMap({ class=${classMap({
// eslint-disable-next-line @typescript-eslint/naming-convention
rating__symbol: true, rating__symbol: true,
// eslint-disable-next-line @typescript-eslint/naming-convention
'rating__symbol--hover': this.isHovering && Math.ceil(displayValue) === index + 1 'rating__symbol--hover': this.isHovering && Math.ceil(displayValue) === index + 1
})} })}
role="presentation" role="presentation"
@ -222,9 +220,7 @@ export default class SlRating extends LitElement {
return html` return html`
<span <span
class=${classMap({ class=${classMap({
// eslint-disable-next-line @typescript-eslint/naming-convention
rating__symbol: true, rating__symbol: true,
// eslint-disable-next-line @typescript-eslint/naming-convention
'rating__symbol--hover': this.isHovering && Math.ceil(displayValue) === index + 1 'rating__symbol--hover': this.isHovering && Math.ceil(displayValue) === index + 1
})} })}
style=${styleMap({ style=${styleMap({

Wyświetl plik

@ -24,7 +24,7 @@ const availableUnits: UnitConfig[] = [
@customElement('sl-relative-time') @customElement('sl-relative-time')
export default class SlRelativeTime extends LitElement { export default class SlRelativeTime extends LitElement {
private readonly localize = new LocalizeController(this); private readonly localize = new LocalizeController(this);
private updateTimeout: NodeJS.Timeout; private updateTimeout: number;
@state() private isoTime = ''; @state() private isoTime = '';
@state() private relativeTime = ''; @state() private relativeTime = '';
@ -102,9 +102,7 @@ export default class SlRelativeTime extends LitElement {
nextInterval = getTimeUntilNextUnit('day'); // next day nextInterval = getTimeUntilNextUnit('day'); // next day
} }
this.updateTimeout = setTimeout(() => { this.updateTimeout = window.setTimeout(() => this.requestUpdate(), nextInterval);
this.requestUpdate();
}, nextInterval);
} }
return html` <time datetime=${this.isoTime} title=${this.titleTime}>${this.relativeTime}</time> `; return html` <time datetime=${this.isoTime} title=${this.titleTime}>${this.relativeTime}</time> `;

Wyświetl plik

@ -51,9 +51,7 @@ export default class SlResizeObserver extends LitElement {
const elements = slot.assignedElements({ flatten: true }) as HTMLElement[]; const elements = slot.assignedElements({ flatten: true }) as HTMLElement[];
// Unwatch previous elements // Unwatch previous elements
this.observedElements.forEach(el => { this.observedElements.forEach(el => this.resizeObserver.unobserve(el));
this.resizeObserver.unobserve(el);
});
this.observedElements = []; this.observedElements = [];
// Watch new elements // Watch new elements

Wyświetl plik

@ -13,7 +13,7 @@ import type SlMenuItem from '~/components/menu-item/menu-item';
import type SlMenu from '~/components/menu/menu'; import type SlMenu from '~/components/menu/menu';
import type { MenuSelectEventDetail } from '~/components/menu/menu'; import type { MenuSelectEventDetail } from '~/components/menu/menu';
import '~/components/tag/tag'; import '~/components/tag/tag';
import { autoIncrement } from '~/internal/autoIncrement'; import { autoIncrement } from '~/internal/auto-increment';
import { emit } from '~/internal/event'; import { emit } from '~/internal/event';
import { FormSubmitController, getLabelledBy, renderFormControl } from '~/internal/form-control'; import { FormSubmitController, getLabelledBy, renderFormControl } from '~/internal/form-control';
import { getTextContent, HasSlotController } from '~/internal/slot'; import { getTextContent, HasSlotController } from '~/internal/slot';
@ -132,11 +132,9 @@ export default class SlSelect extends LitElement {
connectedCallback() { connectedCallback() {
super.connectedCallback(); super.connectedCallback();
this.handleMenuSlotChange = this.handleMenuSlotChange.bind(this); this.handleMenuSlotChange = this.handleMenuSlotChange.bind(this);
this.resizeObserver = new ResizeObserver(() => { this.resizeObserver = new ResizeObserver(() => this.resizeMenu());
this.resizeMenu();
});
void this.updateComplete.then(() => { this.updateComplete.then(() => {
this.resizeObserver.observe(this); this.resizeObserver.observe(this);
this.syncItemsFromValue(); this.syncItemsFromValue();
}); });
@ -163,7 +161,7 @@ export default class SlSelect extends LitElement {
} }
getItemLabel(item: SlMenuItem) { getItemLabel(item: SlMenuItem) {
const slot = item.shadowRoot?.querySelector<HTMLSlotElement>('slot:not([name])'); const slot = item.shadowRoot!.querySelector<HTMLSlotElement>('slot:not([name])');
return getTextContent(slot); return getTextContent(slot);
} }
@ -208,7 +206,7 @@ export default class SlSelect extends LitElement {
@watch('disabled', { waitUntilFirstUpdate: true }) @watch('disabled', { waitUntilFirstUpdate: true })
handleDisabledChange() { handleDisabledChange() {
if (this.disabled && this.isOpen) { if (this.disabled && this.isOpen) {
void this.dropdown.hide(); this.dropdown.hide();
} }
// Disabled form controls are always valid, so we need to recheck validity when the state changes // Disabled form controls are always valid, so we need to recheck validity when the state changes
@ -237,7 +235,7 @@ export default class SlSelect extends LitElement {
// Tabbing out of the control closes it // Tabbing out of the control closes it
if (event.key === 'Tab') { if (event.key === 'Tab') {
if (this.isOpen) { if (this.isOpen) {
void this.dropdown.hide(); this.dropdown.hide();
} }
return; return;
} }
@ -248,7 +246,7 @@ export default class SlSelect extends LitElement {
// Show the menu if it's not already open // Show the menu if it's not already open
if (!this.isOpen) { if (!this.isOpen) {
void this.dropdown.show(); this.dropdown.show();
} }
// Focus on a menu item // Focus on a menu item
@ -274,7 +272,7 @@ export default class SlSelect extends LitElement {
if (!this.isOpen && event.key.length === 1) { if (!this.isOpen && event.key.length === 1) {
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
void this.dropdown.show(); this.dropdown.show();
this.menu.typeToSelect(event.key); this.menu.typeToSelect(event.key);
} }
} }
@ -331,9 +329,7 @@ export default class SlSelect extends LitElement {
values.push(item.value); values.push(item.value);
}); });
await Promise.all(items.map(item => item.render)).then(() => { await Promise.all(items.map(item => item.render)).then(() => this.syncItemsFromValue());
this.syncItemsFromValue();
});
} }
handleTagInteraction(event: KeyboardEvent | MouseEvent) { handleTagInteraction(event: KeyboardEvent | MouseEvent) {
@ -444,9 +440,7 @@ export default class SlSelect extends LitElement {
helpText: this.helpText, helpText: this.helpText,
hasHelpTextSlot, hasHelpTextSlot,
size: this.size, size: this.size,
onLabelClick: () => { onLabelClick: () => this.handleLabelClick()
this.handleLabelClick();
}
}, },
html` html`
<sl-dropdown <sl-dropdown

Wyświetl plik

@ -75,12 +75,8 @@ export default class SlSplitPanel extends LitElement {
connectedCallback() { connectedCallback() {
super.connectedCallback(); super.connectedCallback();
this.resizeObserver = new ResizeObserver(entries => { this.resizeObserver = new ResizeObserver(entries => this.handleResize(entries));
this.handleResize(entries); this.updateComplete.then(() => this.resizeObserver.observe(this));
});
void this.updateComplete.then(() => {
this.resizeObserver.observe(this);
});
this.detectSize(); this.detectSize();
this.cachedPositionInPixels = this.percentageToPixels(this.position); this.cachedPositionInPixels = this.percentageToPixels(this.position);

Wyświetl plik

@ -18,7 +18,7 @@ describe('<sl-switch>', () => {
it('should fire sl-change when clicked', async () => { it('should fire sl-change when clicked', async () => {
const el = await fixture<SlSwitch>(html` <sl-switch></sl-switch> `); const el = await fixture<SlSwitch>(html` <sl-switch></sl-switch> `);
setTimeout(() => el.shadowRoot?.querySelector('input')?.click()); setTimeout(() => el.shadowRoot!.querySelector('input')!.click());
const event = await oneEvent(el, 'sl-change'); const event = await oneEvent(el, 'sl-change');
expect(event.target).to.equal(el); expect(event.target).to.equal(el);
expect(el.checked).to.be.true; expect(el.checked).to.be.true;
@ -27,9 +27,7 @@ describe('<sl-switch>', () => {
it('should fire sl-change when toggled with spacebar', async () => { it('should fire sl-change when toggled with spacebar', async () => {
const el = await fixture<SlSwitch>(html` <sl-switch></sl-switch> `); const el = await fixture<SlSwitch>(html` <sl-switch></sl-switch> `);
el.focus(); el.focus();
setTimeout(() => { setTimeout(() => sendKeys({ press: ' ' }));
void sendKeys({ press: ' ' });
});
const event = await oneEvent(el, 'sl-change'); const event = await oneEvent(el, 'sl-change');
expect(event.target).to.equal(el); expect(event.target).to.equal(el);
expect(el.checked).to.be.true; expect(el.checked).to.be.true;
@ -38,9 +36,7 @@ describe('<sl-switch>', () => {
it('should fire sl-change when toggled with the right arrow', async () => { it('should fire sl-change when toggled with the right arrow', async () => {
const el = await fixture<SlSwitch>(html` <sl-switch></sl-switch> `); const el = await fixture<SlSwitch>(html` <sl-switch></sl-switch> `);
el.focus(); el.focus();
setTimeout(() => { setTimeout(() => sendKeys({ press: 'ArrowRight' }));
void sendKeys({ press: 'ArrowRight' });
});
const event = await oneEvent(el, 'sl-change'); const event = await oneEvent(el, 'sl-change');
expect(event.target).to.equal(el); expect(event.target).to.equal(el);
expect(el.checked).to.be.true; expect(el.checked).to.be.true;
@ -49,9 +45,7 @@ describe('<sl-switch>', () => {
it('should fire sl-change when toggled with the left arrow', async () => { it('should fire sl-change when toggled with the left arrow', async () => {
const el = await fixture<SlSwitch>(html` <sl-switch checked></sl-switch> `); const el = await fixture<SlSwitch>(html` <sl-switch checked></sl-switch> `);
el.focus(); el.focus();
setTimeout(() => { setTimeout(() => sendKeys({ press: 'ArrowLeft' }));
void sendKeys({ press: 'ArrowLeft' });
});
const event = await oneEvent(el, 'sl-change'); const event = await oneEvent(el, 'sl-change');
expect(event.target).to.equal(el); expect(event.target).to.equal(el);
expect(el.checked).to.be.false; expect(el.checked).to.be.false;

Wyświetl plik

@ -4,7 +4,7 @@ import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined.js'; import { ifDefined } from 'lit/directives/if-defined.js';
import { live } from 'lit/directives/live.js'; import { live } from 'lit/directives/live.js';
import styles from './switch.styles'; import styles from './switch.styles';
import { autoIncrement } from '~/internal/autoIncrement'; import { autoIncrement } from '~/internal/auto-increment';
import { emit } from '~/internal/event'; import { emit } from '~/internal/event';
import { FormSubmitController } from '~/internal/form-control'; import { FormSubmitController } from '~/internal/form-control';
import { watch } from '~/internal/watch'; import { watch } from '~/internal/watch';

Wyświetl plik

@ -78,9 +78,7 @@ export default class SlTabGroup extends LitElement {
this.mutationObserver = new MutationObserver(mutations => { this.mutationObserver = new MutationObserver(mutations => {
// Update aria labels when the DOM changes // Update aria labels when the DOM changes
if (mutations.some(m => !['aria-labelledby', 'aria-controls'].includes(m.attributeName!))) { if (mutations.some(m => !['aria-labelledby', 'aria-controls'].includes(m.attributeName!))) {
setTimeout(() => { setTimeout(() => this.setAriaLabels());
this.setAriaLabels();
});
} }
// Sync tabs when disabled states change // Sync tabs when disabled states change
@ -89,7 +87,7 @@ export default class SlTabGroup extends LitElement {
} }
}); });
void this.updateComplete.then(() => { this.updateComplete.then(() => {
this.syncTabsAndPanels(); this.syncTabsAndPanels();
this.mutationObserver.observe(this, { attributes: true, childList: true, subtree: true }); this.mutationObserver.observe(this, { attributes: true, childList: true, subtree: true });
this.resizeObserver.observe(this.nav); this.resizeObserver.observe(this.nav);

Wyświetl plik

@ -1,7 +1,7 @@
import { LitElement, html } from 'lit'; import { LitElement, html } from 'lit';
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import styles from './tab-panel.styles'; import styles from './tab-panel.styles';
import { autoIncrement } from '~/internal/autoIncrement'; import { autoIncrement } from '~/internal/auto-increment';
/** /**
* @since 2.0 * @since 2.0

Wyświetl plik

@ -3,7 +3,7 @@ import { customElement, property, query } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js'; import { classMap } from 'lit/directives/class-map.js';
import styles from './tab.styles'; import styles from './tab.styles';
import '~/components/icon-button/icon-button'; import '~/components/icon-button/icon-button';
import { autoIncrement } from '~/internal/autoIncrement'; import { autoIncrement } from '~/internal/auto-increment';
import { emit } from '~/internal/event'; import { emit } from '~/internal/event';
import { LocalizeController } from '~/utilities/localize'; import { LocalizeController } from '~/utilities/localize';

Wyświetl plik

@ -4,7 +4,7 @@ import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined.js'; import { ifDefined } from 'lit/directives/if-defined.js';
import { live } from 'lit/directives/live.js'; import { live } from 'lit/directives/live.js';
import styles from './textarea.styles'; import styles from './textarea.styles';
import { autoIncrement } from '~/internal/autoIncrement'; import { autoIncrement } from '~/internal/auto-increment';
import { emit } from '~/internal/event'; import { emit } from '~/internal/event';
import { FormSubmitController, getLabelledBy, renderFormControl } from '~/internal/form-control'; import { FormSubmitController, getLabelledBy, renderFormControl } from '~/internal/form-control';
import { HasSlotController } from '~/internal/slot'; import { HasSlotController } from '~/internal/slot';
@ -116,11 +116,9 @@ export default class SlTextarea extends LitElement {
connectedCallback() { connectedCallback() {
super.connectedCallback(); super.connectedCallback();
this.resizeObserver = new ResizeObserver(() => { this.resizeObserver = new ResizeObserver(() => this.setTextareaHeight());
this.setTextareaHeight();
});
void this.updateComplete.then(() => { this.updateComplete.then(() => {
this.setTextareaHeight(); this.setTextareaHeight();
this.resizeObserver.observe(this.input); this.resizeObserver.observe(this.input);
}); });
@ -151,7 +149,7 @@ export default class SlTextarea extends LitElement {
} }
/** Gets or sets the textarea's scroll position. */ /** Gets or sets the textarea's scroll position. */
scrollPosition(position?: { top?: number; left?: number }): void; scrollPosition(position: { top?: number; left?: number }): void;
scrollPosition(): { top: number; left: number }; scrollPosition(): { top: number; left: number };
scrollPosition(position?: { top?: number; left?: number }): { top: number; left: number } | undefined { scrollPosition(position?: { top?: number; left?: number }): { top: number; left: number } | undefined {
if (typeof position !== 'undefined') { if (typeof position !== 'undefined') {

Wyświetl plik

@ -37,7 +37,7 @@ describe('<sl-tooltip>', () => {
el.addEventListener('sl-show', showHandler); el.addEventListener('sl-show', showHandler);
el.addEventListener('sl-after-show', afterShowHandler); el.addEventListener('sl-after-show', afterShowHandler);
void el.show(); el.show();
await waitUntil(() => showHandler.calledOnce); await waitUntil(() => showHandler.calledOnce);
await waitUntil(() => afterShowHandler.calledOnce); await waitUntil(() => afterShowHandler.calledOnce);
@ -59,7 +59,7 @@ describe('<sl-tooltip>', () => {
el.addEventListener('sl-hide', hideHandler); el.addEventListener('sl-hide', hideHandler);
el.addEventListener('sl-after-hide', afterHideHandler); el.addEventListener('sl-after-hide', afterHideHandler);
void el.hide(); el.hide();
await waitUntil(() => hideHandler.calledOnce); await waitUntil(() => hideHandler.calledOnce);
await waitUntil(() => afterHideHandler.calledOnce); await waitUntil(() => afterHideHandler.calledOnce);

Wyświetl plik

@ -39,7 +39,7 @@ export default class SlTooltip extends LitElement {
private target: HTMLElement; private target: HTMLElement;
private popover?: PopperInstance; private popover?: PopperInstance;
private hoverTimeout: NodeJS.Timeout; private hoverTimeout: number;
/** The tooltip's content. Alternatively, you can use the content slot. */ /** The tooltip's content. Alternatively, you can use the content slot. */
@property() content = ''; @property() content = '';
@ -96,7 +96,7 @@ export default class SlTooltip extends LitElement {
this.handleMouseOver = this.handleMouseOver.bind(this); this.handleMouseOver = this.handleMouseOver.bind(this);
this.handleMouseOut = this.handleMouseOut.bind(this); this.handleMouseOut = this.handleMouseOut.bind(this);
void this.updateComplete.then(() => { this.updateComplete.then(() => {
this.addEventListener('blur', this.handleBlur, true); this.addEventListener('blur', this.handleBlur, true);
this.addEventListener('focus', this.handleFocus, true); this.addEventListener('focus', this.handleFocus, true);
this.addEventListener('click', this.handleClick); this.addEventListener('click', this.handleClick);
@ -160,23 +160,23 @@ export default class SlTooltip extends LitElement {
handleBlur() { handleBlur() {
if (this.hasTrigger('focus')) { if (this.hasTrigger('focus')) {
void this.hide(); this.hide();
} }
} }
handleClick() { handleClick() {
if (this.hasTrigger('click')) { if (this.hasTrigger('click')) {
if (this.open) { if (this.open) {
void this.hide(); this.hide();
} else { } else {
void this.show(); this.show();
} }
} }
} }
handleFocus() { handleFocus() {
if (this.hasTrigger('focus')) { if (this.hasTrigger('focus')) {
void this.show(); this.show();
} }
} }
@ -184,7 +184,7 @@ export default class SlTooltip extends LitElement {
// Pressing escape when the target element has focus should dismiss the tooltip // Pressing escape when the target element has focus should dismiss the tooltip
if (this.open && event.key === 'Escape') { if (this.open && event.key === 'Escape') {
event.stopPropagation(); event.stopPropagation();
void this.hide(); this.hide();
} }
} }
@ -192,7 +192,7 @@ export default class SlTooltip extends LitElement {
if (this.hasTrigger('hover')) { if (this.hasTrigger('hover')) {
const delay = parseDuration(getComputedStyle(this).getPropertyValue('--show-delay')); const delay = parseDuration(getComputedStyle(this).getPropertyValue('--show-delay'));
clearTimeout(this.hoverTimeout); clearTimeout(this.hoverTimeout);
this.hoverTimeout = setTimeout(() => void this.show(), delay); this.hoverTimeout = window.setTimeout(() => void this.show(), delay);
} }
} }
@ -200,7 +200,7 @@ export default class SlTooltip extends LitElement {
if (this.hasTrigger('hover')) { if (this.hasTrigger('hover')) {
const delay = parseDuration(getComputedStyle(this).getPropertyValue('--hide-delay')); const delay = parseDuration(getComputedStyle(this).getPropertyValue('--hide-delay'));
clearTimeout(this.hoverTimeout); clearTimeout(this.hoverTimeout);
this.hoverTimeout = setTimeout(() => void this.hide(), delay); this.hoverTimeout = window.setTimeout(() => void this.hide(), delay);
} }
} }
@ -268,14 +268,14 @@ export default class SlTooltip extends LitElement {
@watch('content') @watch('content')
handleContentChange() { handleContentChange() {
if (this.open) { if (this.open) {
void this.popover?.update(); this.popover?.update();
} }
} }
@watch('disabled') @watch('disabled')
handleDisabledChange() { handleDisabledChange() {
if (this.disabled && this.open) { if (this.disabled && this.open) {
void this.hide(); this.hide();
} }
} }
@ -285,7 +285,7 @@ export default class SlTooltip extends LitElement {
} }
syncOptions() { syncOptions() {
void this.popover?.setOptions({ this.popover?.setOptions({
placement: this.placement, placement: this.placement,
strategy: this.hoist ? 'fixed' : 'absolute', strategy: this.hoist ? 'fixed' : 'absolute',
modifiers: [ modifiers: [

Wyświetl plik

@ -162,9 +162,7 @@ export function renderFormControl(
class="form-control__label" class="form-control__label"
for=${props.inputId} for=${props.inputId}
aria-hidden=${hasLabel ? 'false' : 'true'} aria-hidden=${hasLabel ? 'false' : 'true'}
@click=${(event: MouseEvent) => { @click=${(event: MouseEvent) => props.onLabelClick?.(event)}
props.onLabelClick?.(event);
}}
> >
<slot name="label">${props.label}</slot> <slot name="label">${props.label}</slot>
</label> </label>

Wyświetl plik

@ -0,0 +1,4 @@
export function isTruthy<T>(obj: T | T[] | undefined | null | '' | [] | 0 | false): obj is T | T[] {
// eslint-disable-next-line no-restricted-syntax -- we do intentionally want the type coercion behavior
return Boolean(obj);
}

Wyświetl plik

@ -6,7 +6,7 @@ const numberFormatter = new Intl.NumberFormat();
export function formatBytes(bytes: number, options: FormatBytesOptions) { export function formatBytes(bytes: number, options: FormatBytesOptions) {
options = { options = {
unit: 'bytes', unit: 'bytes',
formatter: (number: number) => numberFormatter.format(number), formatter: (num: number) => numberFormatter.format(num),
...options ...options
}; };

Wyświetl plik

@ -67,9 +67,7 @@ export function getTabbableBoundary(root: HTMLElement | ShadowRoot) {
} }
} }
[...el.querySelectorAll('*')].forEach((e: HTMLElement) => { [...el.querySelectorAll('*')].forEach((e: HTMLElement) => walk(e));
walk(e);
});
} }
// Collect all elements including the root // Collect all elements including the root

Wyświetl plik

@ -13,11 +13,11 @@
// } // }
import type { LitElement } from 'lit'; import type { LitElement } from 'lit';
import type { NonUndefined } from 'utility-types';
type UpdateHandler = (prev?: unknown, next?: unknown) => void; type UpdateHandler = (prev?: unknown, next?: unknown) => void;
// Mostly copied from utility-types' FunctionKeys type but this uses a specific function signature type NonUndefined<A> = A extends undefined ? never : A;
type UpdateHandlerFunctionKeys<T extends object> = { type UpdateHandlerFunctionKeys<T extends object> = {
[K in keyof T]-?: NonUndefined<T[K]> extends UpdateHandler ? K : never; [K in keyof T]-?: NonUndefined<T[K]> extends UpdateHandler ? K : never;
}[keyof T]; }[keyof T];