Merge pull request from koloml/fix-autocomplete-popup-on-mobile

Autocomplete Popup: Fixed `Enter` key presses not hiding popup in the Tag Editor on Android devices
This commit is contained in:
liamwhite 2025-04-03 12:57:51 -04:00 committed by GitHub
commit 2958405355
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 234 additions and 352 deletions

View file

@ -1,5 +1,5 @@
import tsEslint from 'typescript-eslint';
import vitestPlugin from 'eslint-plugin-vitest';
import vitestPlugin from '@vitest/eslint-plugin';
import globals from 'globals';
export default tsEslint.config(

View file

@ -146,7 +146,7 @@ export class TestContext {
await vi.runAllTimersAsync();
}
async keyDown(code: string, params?: { ctrlKey?: boolean }) {
async keyDown(code: string, params?: { ctrlKey?: boolean; key?: string }) {
fireEvent.keyDown(this.input, { code, ...(params ?? {}) });
await vi.runAllTimersAsync();
}

View file

@ -1,114 +1,146 @@
import { init } from './context';
import { init, TestContext } from './context';
it('supports navigation via keyboard', async () => {
const ctx = await init();
describe('Autocomplete keyboard navigation', () => {
let ctx: TestContext;
await ctx.setInput('f');
beforeAll(async () => {
ctx = await init();
});
await ctx.keyDown('ArrowDown');
it('supports navigation via keyboard', async () => {
await ctx.setInput('f');
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest<>",
"suggestions": [
"👉 forest 3",
"force field 1",
"fog 1",
"flower 1",
],
}
`);
await ctx.keyDown('ArrowDown');
await ctx.keyDown('ArrowDown');
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest<>",
"suggestions": [
"👉 forest 3",
"force field 1",
"fog 1",
"flower 1",
],
}
`);
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "force field<>",
"suggestions": [
"forest 3",
"👉 force field 1",
"fog 1",
"flower 1",
],
}
`);
await ctx.keyDown('ArrowDown');
await ctx.keyDown('ArrowDown', { ctrlKey: true });
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "force field<>",
"suggestions": [
"forest 3",
"👉 force field 1",
"fog 1",
"flower 1",
],
}
`);
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "flower<>",
"suggestions": [
"forest 3",
"force field 1",
"fog 1",
"👉 flower 1",
],
}
`);
await ctx.keyDown('ArrowDown', { ctrlKey: true });
await ctx.keyDown('ArrowUp', { ctrlKey: true });
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "flower<>",
"suggestions": [
"forest 3",
"force field 1",
"fog 1",
"👉 flower 1",
],
}
`);
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest<>",
"suggestions": [
"👉 forest 3",
"force field 1",
"fog 1",
"flower 1",
],
}
`);
await ctx.keyDown('ArrowUp', { ctrlKey: true });
await ctx.keyDown('Enter');
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest<>",
"suggestions": [
"👉 forest 3",
"force field 1",
"fog 1",
"flower 1",
],
}
`);
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest<>",
"suggestions": [],
}
`);
await ctx.keyDown('Enter');
await ctx.setInput('forest, t<>, safe');
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest<>",
"suggestions": [],
}
`);
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest, t<>, safe",
"suggestions": [
"artist:test 1",
],
}
`);
await ctx.setInput('forest, t<>, safe');
await ctx.keyDown('ArrowDown');
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest, t<>, safe",
"suggestions": [
"artist:test 1",
],
}
`);
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest, artist:test<>, safe",
"suggestions": [
"👉 artist:test 1",
],
}
`);
await ctx.keyDown('ArrowDown');
await ctx.keyDown('Escape');
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest, artist:test<>, safe",
"suggestions": [
"👉 artist:test 1",
],
}
`);
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest, artist:test<>, safe",
"suggestions": [],
}
`);
await ctx.keyDown('Escape');
await ctx.setInput('forest, t<>, safe');
await ctx.keyDown('ArrowDown');
await ctx.keyDown('Enter');
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest, artist:test<>, safe",
"suggestions": [],
}
`);
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest, artist:test<>, safe",
"suggestions": [],
}
`);
await ctx.setInput('forest, t<>, safe');
await ctx.keyDown('ArrowDown');
await ctx.keyDown('Enter');
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest, artist:test<>, safe",
"suggestions": [],
}
`);
});
it('should handle Enter key presses with empty code property', async () => {
await ctx.setInput('f');
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "f<>",
"suggestions": [
"forest 3",
"force field 1",
"fog 1",
"flower 1",
],
}
`);
await ctx.keyDown('ArrowDown');
await ctx.keyDown('', { key: 'Enter' });
ctx.expectUi().toMatchInlineSnapshot(`
{
"input": "forest<>",
"suggestions": [],
}
`);
});
});

View file

@ -2,12 +2,12 @@ import { LocalAutocompleter } from '../utils/local-autocompleter';
import * as history from './history';
import { AutocompletableInput, TextInputElement } from './input';
import {
SuggestionsPopupComponent,
Suggestions,
TagSuggestionComponent,
Suggestion,
HistorySuggestionComponent,
ItemSelectedEvent,
Suggestion,
Suggestions,
SuggestionsPopupComponent,
TagSuggestionComponent,
} from '../utils/suggestions-view';
import { prefixMatchParts } from '../utils/suggestions-model';
import { $$ } from '../utils/dom';
@ -243,13 +243,21 @@ class Autocomplete {
if (!this.isActive() || this.input.element !== event.target) {
return;
}
if ((event.key === ',' || event.code === 'Enter') && this.input.type === 'single-tag') {
let keyCode = event.code;
// Chrome & Firefox on Android devices return empty code when "Enter" is pressed.
if (!keyCode && event.key === 'Enter') {
keyCode = event.key;
}
if ((event.key === ',' || keyCode === 'Enter') && this.input.type === 'single-tag') {
// Comma/Enter mean the end of input for the current tag in single-tag mode.
this.hidePopup(`The user accepted the existing input via key: '${event.key}', code: '${event.code}'`);
return;
}
switch (event.code) {
switch (keyCode) {
case 'Enter': {
const { selectedSuggestion } = this.popup;
if (!selectedSuggestion) {

340
assets/package-lock.json generated
View file

@ -21,11 +21,11 @@
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
"@vitest/coverage-v8": "^2.1.9",
"@vitest/eslint-plugin": "^1.1.38",
"eslint": "^9.16.0",
"eslint-plugin-vitest": "^0.5.4",
"stylelint": "^16.11.0",
"stylelint-config-standard": "^36.0.1",
"typescript-eslint": "8.17.0",
"typescript-eslint": "8.29.0",
"vitest": "^2.1.9",
"vitest-fetch-mock": "^0.4.2"
}
@ -1443,20 +1443,20 @@
"integrity": "sha512-jxXqkf4sBn/WV9YsOlB5fFzWo9kGafMDF62VmVC1mFF367BuRn/2txr0ZaEchPsNIvyiLckMpxO6Xz3knpC6Nw=="
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.17.0.tgz",
"integrity": "sha512-HU1KAdW3Tt8zQkdvNoIijfWDMvdSweFYm4hWh+KwhPstv+sCmWb89hCIP8msFm9N1R/ooh9honpSuvqKWlYy3w==",
"version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.0.tgz",
"integrity": "sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.17.0",
"@typescript-eslint/type-utils": "8.17.0",
"@typescript-eslint/utils": "8.17.0",
"@typescript-eslint/visitor-keys": "8.17.0",
"@typescript-eslint/scope-manager": "8.29.0",
"@typescript-eslint/type-utils": "8.29.0",
"@typescript-eslint/utils": "8.29.0",
"@typescript-eslint/visitor-keys": "8.29.0",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
"ts-api-utils": "^1.3.0"
"ts-api-utils": "^2.0.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -1467,24 +1467,20 @@
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
"eslint": "^8.57.0 || ^9.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.17.0.tgz",
"integrity": "sha512-Drp39TXuUlD49F7ilHHCG7TTg8IkA+hxCuULdmzWYICxGXvDXmDmWEjJYZQYgf6l/TFfYNE167m7isnc3xlIEg==",
"version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.0.tgz",
"integrity": "sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.17.0",
"@typescript-eslint/types": "8.17.0",
"@typescript-eslint/typescript-estree": "8.17.0",
"@typescript-eslint/visitor-keys": "8.17.0",
"@typescript-eslint/scope-manager": "8.29.0",
"@typescript-eslint/types": "8.29.0",
"@typescript-eslint/typescript-estree": "8.29.0",
"@typescript-eslint/visitor-keys": "8.29.0",
"debug": "^4.3.4"
},
"engines": {
@ -1495,22 +1491,18 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.17.0.tgz",
"integrity": "sha512-/ewp4XjvnxaREtqsZjF4Mfn078RD/9GmiEAtTeLQ7yFdKnqwTOgRMSvFz4et9U5RiJQ15WTGXPLj89zGusvxBg==",
"version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.0.tgz",
"integrity": "sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "8.17.0",
"@typescript-eslint/visitor-keys": "8.17.0"
"@typescript-eslint/types": "8.29.0",
"@typescript-eslint/visitor-keys": "8.29.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -1521,15 +1513,15 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.17.0.tgz",
"integrity": "sha512-q38llWJYPd63rRnJ6wY/ZQqIzPrBCkPdpIsaCfkR3Q4t3p6sb422zougfad4TFW9+ElIFLVDzWGiGAfbb/v2qw==",
"version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.29.0.tgz",
"integrity": "sha512-ahaWQ42JAOx+NKEf5++WC/ua17q5l+j1GFrbbpVKzFL/tKVc0aYY8rVSYUpUvt2hUP1YBr7mwXzx+E/DfUWI9Q==",
"dev": true,
"dependencies": {
"@typescript-eslint/typescript-estree": "8.17.0",
"@typescript-eslint/utils": "8.17.0",
"@typescript-eslint/typescript-estree": "8.29.0",
"@typescript-eslint/utils": "8.29.0",
"debug": "^4.3.4",
"ts-api-utils": "^1.3.0"
"ts-api-utils": "^2.0.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -1539,18 +1531,14 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.17.0.tgz",
"integrity": "sha512-gY2TVzeve3z6crqh2Ic7Cr+CAv6pfb0Egee7J5UAVWCpVvDI/F71wNfolIim4FE6hT15EbpZFVUj9j5i38jYXA==",
"version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.0.tgz",
"integrity": "sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg==",
"dev": true,
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -1561,19 +1549,19 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.17.0.tgz",
"integrity": "sha512-JqkOopc1nRKZpX+opvKqnM3XUlM7LpFMD0lYxTqOTKQfCWAmxw45e3qlOCsEqEB2yuacujivudOFpCnqkBDNMw==",
"version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.0.tgz",
"integrity": "sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "8.17.0",
"@typescript-eslint/visitor-keys": "8.17.0",
"@typescript-eslint/types": "8.29.0",
"@typescript-eslint/visitor-keys": "8.29.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
"minimatch": "^9.0.4",
"semver": "^7.6.0",
"ts-api-utils": "^1.3.0"
"ts-api-utils": "^2.0.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -1582,10 +1570,8 @@
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
"peerDependencies": {
"typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
@ -1613,15 +1599,15 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.17.0.tgz",
"integrity": "sha512-bQC8BnEkxqG8HBGKwG9wXlZqg37RKSMY7v/X8VEWD8JG2JuTHuNK0VFvMPMUKQcbk6B+tf05k+4AShAEtCtJ/w==",
"version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.29.0.tgz",
"integrity": "sha512-gX/A0Mz9Bskm8avSWFcK0gP7cZpbY4AIo6B0hWYFCaIsz750oaiWR4Jr2CI+PQhfW1CpcQr9OlfPS+kMFegjXA==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@typescript-eslint/scope-manager": "8.17.0",
"@typescript-eslint/types": "8.17.0",
"@typescript-eslint/typescript-estree": "8.17.0"
"@typescript-eslint/scope-manager": "8.29.0",
"@typescript-eslint/types": "8.29.0",
"@typescript-eslint/typescript-estree": "8.29.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -1631,21 +1617,17 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.17.0.tgz",
"integrity": "sha512-1Hm7THLpO6ww5QU6H/Qp+AusUUl+z/CAm3cNZZ0jQvon9yicgO7Rwd+/WWRpMKLYV6p2UvdbR27c86rzCPpreg==",
"version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.0.tgz",
"integrity": "sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "8.17.0",
"@typescript-eslint/types": "8.29.0",
"eslint-visitor-keys": "^4.2.0"
},
"engines": {
@ -1689,6 +1671,27 @@
}
}
},
"node_modules/@vitest/eslint-plugin": {
"version": "1.1.38",
"resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.1.38.tgz",
"integrity": "sha512-KcOTZyVz8RiM5HyriiDVrP1CyBGuhRxle+lBsmSs6NTJEO/8dKVAq+f5vQzHj1/Kc7bYXSDO6yBe62Zx0t5iaw==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"@typescript-eslint/utils": "^8.24.0",
"eslint": ">= 8.57.0",
"typescript": ">= 5.0.0",
"vitest": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
},
"vitest": {
"optional": true
}
}
},
"node_modules/@vitest/expect": {
"version": "2.1.9",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz",
@ -2501,163 +2504,6 @@
}
}
},
"node_modules/eslint-plugin-vitest": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.5.4.tgz",
"integrity": "sha512-um+odCkccAHU53WdKAw39MY61+1x990uXjSPguUCq3VcEHdqJrOb8OTMrbYlY6f9jAKx7x98kLVlIe3RJeJqoQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/utils": "^7.7.1"
},
"engines": {
"node": "^18.0.0 || >= 20.0.0"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
"vitest": "*"
},
"peerDependenciesMeta": {
"@typescript-eslint/eslint-plugin": {
"optional": true
},
"vitest": {
"optional": true
}
}
},
"node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/scope-manager": {
"version": "7.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz",
"integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "7.18.0",
"@typescript-eslint/visitor-keys": "7.18.0"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/types": {
"version": "7.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz",
"integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==",
"dev": true,
"engines": {
"node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/typescript-estree": {
"version": "7.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz",
"integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "7.18.0",
"@typescript-eslint/visitor-keys": "7.18.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
"minimatch": "^9.0.4",
"semver": "^7.6.0",
"ts-api-utils": "^1.3.0"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/utils": {
"version": "7.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz",
"integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@typescript-eslint/scope-manager": "7.18.0",
"@typescript-eslint/types": "7.18.0",
"@typescript-eslint/typescript-estree": "7.18.0"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.56.0"
}
},
"node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/visitor-keys": {
"version": "7.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz",
"integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "7.18.0",
"eslint-visitor-keys": "^3.4.3"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/eslint-plugin-vitest/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/eslint-plugin-vitest/node_modules/eslint-visitor-keys": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-plugin-vitest/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/eslint-scope": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz",
@ -4858,15 +4704,15 @@
}
},
"node_modules/ts-api-utils": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
"integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
"dev": true,
"engines": {
"node": ">=16"
"node": ">=18.12"
},
"peerDependencies": {
"typescript": ">=4.2.0"
"typescript": ">=4.8.4"
}
},
"node_modules/type-check": {
@ -4894,14 +4740,14 @@
}
},
"node_modules/typescript-eslint": {
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.17.0.tgz",
"integrity": "sha512-409VXvFd/f1br1DCbuKNFqQpXICoTB+V51afcwG1pn1a3Cp92MqAUges3YjwEdQ0cMUoCIodjVDAYzyD8h3SYA==",
"version": "8.29.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.29.0.tgz",
"integrity": "sha512-ep9rVd9B4kQsZ7ZnWCVxUE/xDLUUUsRzE0poAeNu+4CkFErLfuvPt/qtm2EpnSyfvsR0S6QzDFSrPCFBwf64fg==",
"dev": true,
"dependencies": {
"@typescript-eslint/eslint-plugin": "8.17.0",
"@typescript-eslint/parser": "8.17.0",
"@typescript-eslint/utils": "8.17.0"
"@typescript-eslint/eslint-plugin": "8.29.0",
"@typescript-eslint/parser": "8.29.0",
"@typescript-eslint/utils": "8.29.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -4911,12 +4757,8 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/undici-types": {

View file

@ -26,11 +26,11 @@
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
"@vitest/coverage-v8": "^2.1.9",
"@vitest/eslint-plugin": "^1.1.38",
"eslint": "^9.16.0",
"eslint-plugin-vitest": "^0.5.4",
"stylelint": "^16.11.0",
"stylelint-config-standard": "^36.0.1",
"typescript-eslint": "8.17.0",
"typescript-eslint": "8.29.0",
"vitest": "^2.1.9",
"vitest-fetch-mock": "^0.4.2"
}