chore: migrate to eslint-better-tailwind (#31969)

This commit is contained in:
Stephen Zhou 2026-02-05 17:36:08 +08:00 committed by GitHub
parent be8f265e43
commit 7202a24bcf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 941 additions and 367 deletions

View File

@ -79,29 +79,6 @@ jobs:
find . -name "*.py" -type f -exec sed -i.bak -E 's/"([^"]+)" \| None/Optional["\1"]/g; s/'"'"'([^'"'"']+)'"'"' \| None/Optional['"'"'\1'"'"']/g' {} \;
find . -name "*.py.bak" -type f -delete
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
package_json_file: web/package.json
run_install: false
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
cache-dependency-path: ./web/pnpm-lock.yaml
- name: Install web dependencies
run: |
cd web
pnpm install --frozen-lockfile
- name: ESLint autofix
run: |
cd web
pnpm lint:fix || true
# mdformat breaks YAML front matter in markdown files. Add --exclude for directories containing YAML front matter.
- name: mdformat
run: |

View File

@ -1,4 +1,3 @@
/* eslint-disable tailwindcss/classnames-order */
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import Effect from '.'
@ -29,8 +28,8 @@ type Story = StoryObj<typeof meta>
export const Playground: Story = {
render: () => (
<div className="relative h-40 w-72 overflow-hidden rounded-2xl border border-divider-subtle bg-background-default-subtle">
<Effect className="top-6 left-8" />
<Effect className="top-14 right-10 bg-util-colors-purple-brand-purple-brand-500" />
<Effect className="left-8 top-6" />
<Effect className="bg-util-colors-purple-brand-purple-brand-500 right-10 top-14" />
<div className="absolute inset-x-0 bottom-4 flex justify-center text-xs text-text-secondary">
Accent glow
</div>

View File

@ -14,7 +14,6 @@ const ErrorMessage = ({
errorMsg,
}: ErrorMessageProps) => {
return (
// eslint-disable-next-line tailwindcss/migration-from-tailwind-2
<div className={cn(
'flex gap-x-0.5 rounded-xl border-[0.5px] border-components-panel-border bg-opacity-40 bg-toast-error-bg p-2 shadow-xs shadow-shadow-shadow-3',
className,

View File

@ -38,6 +38,11 @@ pnpm lint:tss
This command lints the entire project and is intended for final verification before committing or pushing changes.
### Introducing New Plugins or Rules
If a new rule causes many existing code errors or automatic fixes generate too many diffs, do not use the `--fix` option for automatic fixes.
You can introduce the rule first, then use the `--suppress-all` option to temporarily suppress these errors, and gradually fix them in subsequent changes.
## Type Check
You should be able to see suggestions from TypeScript in your editor for all open files.

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
// @ts-check
import antfu from '@antfu/eslint-config'
import pluginQuery from '@tanstack/eslint-plugin-query'
import tailwindcss from 'eslint-plugin-better-tailwindcss'
import sonar from 'eslint-plugin-sonarjs'
import storybook from 'eslint-plugin-storybook'
import tailwind from 'eslint-plugin-tailwindcss'
import dify from './eslint-rules/index.js'
export default antfu(
@ -23,7 +23,7 @@ export default antfu(
},
},
nextjs: true,
ignores: ['public', 'types/doc-paths.ts'],
ignores: ['public', 'types/doc-paths.ts', 'eslint-suppressions.json'],
typescript: {
overrides: {
'ts/consistent-type-definitions': ['error', 'type'],
@ -66,42 +66,16 @@ export default antfu(
sonarjs: sonar,
},
},
tailwind.configs['flat/recommended'],
{
settings: {
tailwindcss: {
// These are the default values but feel free to customize
callees: ['classnames', 'clsx', 'ctl', 'cn', 'classNames'],
config: 'tailwind.config.js', // returned from `loadConfig()` utility if not provided
cssFiles: [
'**/*.css',
'!**/node_modules',
'!**/.*',
'!**/dist',
'!**/build',
'!**/.storybook',
'!**/.next',
'!**/.public',
],
cssFilesRefreshRate: 5_000,
removeDuplicates: true,
skipClassAttribute: false,
whitelist: [],
tags: [], // can be set to e.g. ['tw'] for use in tw`bg-blue`
classRegex: '^class(Name)?$', // can be modified to support custom attributes. E.g. "^tw$" for `twin.macro`
},
files: ['**/*.{ts,tsx}'],
plugins: {
tailwindcss,
},
rules: {
// due to 1k lines of tailwind config, these rule have performance issue
'tailwindcss/no-contradicting-classname': 'off',
'tailwindcss/enforces-shorthand': 'off',
'tailwindcss/no-custom-classname': 'off',
'tailwindcss/no-unnecessary-arbitrary-value': 'off',
'tailwindcss/no-arbitrary-value': 'off',
'tailwindcss/classnames-order': 'warn',
'tailwindcss/enforces-negative-arbitrary-values': 'warn',
'tailwindcss/migration-from-tailwind-2': 'warn',
'tailwindcss/enforce-consistent-class-order': 'error',
'tailwindcss/no-duplicate-classes': 'error',
'tailwindcss/no-unnecessary-whitespace': 'error',
'tailwindcss/no-unknown-classes': 'warn',
},
},
{

View File

@ -154,7 +154,7 @@
"sharp": "0.33.5",
"sortablejs": "1.15.6",
"string-ts": "2.3.1",
"tailwind-merge": "2.6.0",
"tailwind-merge": "2.6.1",
"tldts": "7.0.17",
"ufo": "1.6.3",
"use-context-selector": "2.0.0",
@ -166,7 +166,7 @@
"devDependencies": {
"@antfu/eslint-config": "7.2.0",
"@chromatic-com/storybook": "5.0.0",
"@eslint-react/eslint-plugin": "2.8.1",
"@eslint-react/eslint-plugin": "2.9.4",
"@mdx-js/loader": "3.1.1",
"@mdx-js/react": "3.1.1",
"@next/bundle-analyzer": "16.1.5",
@ -180,7 +180,7 @@
"@storybook/addon-themes": "10.2.0",
"@storybook/nextjs-vite": "10.2.0",
"@storybook/react": "10.2.0",
"@tanstack/eslint-plugin-query": "5.91.3",
"@tanstack/eslint-plugin-query": "5.91.4",
"@tanstack/react-devtools": "0.9.2",
"@tanstack/react-form-devtools": "0.2.12",
"@tanstack/react-query-devtools": "5.90.2",
@ -213,11 +213,11 @@
"cross-env": "10.1.0",
"esbuild": "0.27.2",
"eslint": "9.39.2",
"eslint-plugin-better-tailwindcss": "4.1.1",
"eslint-plugin-react-hooks": "7.0.1",
"eslint-plugin-react-refresh": "0.4.26",
"eslint-plugin-react-refresh": "0.5.0",
"eslint-plugin-sonarjs": "3.0.6",
"eslint-plugin-storybook": "10.2.1",
"eslint-plugin-tailwindcss": "3.18.2",
"eslint-plugin-storybook": "10.2.6",
"husky": "9.1.7",
"jsdom": "27.3.0",
"jsdom-testing-mocks": "1.16.0",
@ -229,7 +229,7 @@
"sass": "1.93.2",
"serwist": "9.5.4",
"storybook": "10.2.0",
"tailwindcss": "3.4.18",
"tailwindcss": "3.4.19",
"tsx": "4.21.0",
"typescript": "5.9.3",
"uglify-js": "3.19.3",

View File

@ -127,7 +127,7 @@ importers:
version: 3.2.5
'@tailwindcss/typography':
specifier: 0.5.19
version: 0.5.19(tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.2))
version: 0.5.19(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2))
'@tanstack/react-form':
specifier: 1.23.7
version: 1.23.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@ -342,8 +342,8 @@ importers:
specifier: 2.3.1
version: 2.3.1
tailwind-merge:
specifier: 2.6.0
version: 2.6.0
specifier: 2.6.1
version: 2.6.1
tldts:
specifier: 7.0.17
version: 7.0.17
@ -368,13 +368,13 @@ importers:
devDependencies:
'@antfu/eslint-config':
specifier: 7.2.0
version: 7.2.0(@eslint-react/eslint-plugin@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@16.1.6)(@vue/compiler-sfc@3.5.27)(eslint-plugin-react-hooks@7.0.1(eslint@9.39.2(jiti@1.21.7)))(eslint-plugin-react-refresh@0.4.26(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)(vitest@4.0.17)
version: 7.2.0(@eslint-react/eslint-plugin@2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@16.1.6)(@vue/compiler-sfc@3.5.27)(eslint-plugin-react-hooks@7.0.1(eslint@9.39.2(jiti@1.21.7)))(eslint-plugin-react-refresh@0.5.0(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)(vitest@4.0.17)
'@chromatic-com/storybook':
specifier: 5.0.0
version: 5.0.0(storybook@10.2.0(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))
'@eslint-react/eslint-plugin':
specifier: 2.8.1
version: 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
specifier: 2.9.4
version: 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@mdx-js/loader':
specifier: 3.1.1
version: 3.1.1(webpack@5.104.1(esbuild@0.27.2)(uglify-js@3.19.3))
@ -415,8 +415,8 @@ importers:
specifier: 10.2.0
version: 10.2.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.0(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)
'@tanstack/eslint-plugin-query':
specifier: 5.91.3
version: 5.91.3(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
specifier: 5.91.4
version: 5.91.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@tanstack/react-devtools':
specifier: 0.9.2
version: 0.9.2(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.11)
@ -513,21 +513,21 @@ importers:
eslint:
specifier: 9.39.2
version: 9.39.2(jiti@1.21.7)
eslint-plugin-better-tailwindcss:
specifier: 4.1.1
version: 4.1.1(eslint@9.39.2(jiti@1.21.7))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2))(typescript@5.9.3)
eslint-plugin-react-hooks:
specifier: 7.0.1
version: 7.0.1(eslint@9.39.2(jiti@1.21.7))
eslint-plugin-react-refresh:
specifier: 0.4.26
version: 0.4.26(eslint@9.39.2(jiti@1.21.7))
specifier: 0.5.0
version: 0.5.0(eslint@9.39.2(jiti@1.21.7))
eslint-plugin-sonarjs:
specifier: 3.0.6
version: 3.0.6(eslint@9.39.2(jiti@1.21.7))
eslint-plugin-storybook:
specifier: 10.2.1
version: 10.2.1(eslint@9.39.2(jiti@1.21.7))(storybook@10.2.0(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)
eslint-plugin-tailwindcss:
specifier: 3.18.2
version: 3.18.2(tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.2))
specifier: 10.2.6
version: 10.2.6(eslint@9.39.2(jiti@1.21.7))(storybook@10.2.0(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)
husky:
specifier: 9.1.7
version: 9.1.7
@ -562,8 +562,8 @@ importers:
specifier: 10.2.0
version: 10.2.0(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
tailwindcss:
specifier: 3.4.18
version: 3.4.18(tsx@4.21.0)(yaml@2.8.2)
specifier: 3.4.19
version: 3.4.19(tsx@4.21.0)(yaml@2.8.2)
tsx:
specifier: 4.21.0
version: 4.21.0
@ -1124,40 +1124,40 @@ packages:
resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
'@eslint-react/ast@2.8.1':
resolution: {integrity: sha512-4D442lxeFvvd9PMvBbA621rfz/Ne8Kod8RW0/FLKO0vx+IOxm74pP6be1uU56rqL9TvoIHxjclBjfgXplEF+Yw==}
'@eslint-react/ast@2.9.4':
resolution: {integrity: sha512-WI9iq5ePTlcWo0xhSs4wxLUC6u4QuBmQkKeSiXexkEO8C2p8QE7ECNIXhRVkYs3p3AKH5xTez9V8C/CBIGxeXA==}
engines: {node: '>=20.19.0'}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@eslint-react/core@2.8.1':
resolution: {integrity: sha512-zF73p8blyuX+zrfgyTtpKesichYzK+G54TEjFWtzagWIbnqQjtVscebL/eGep72oWzAOd5B04ACBvJ2hW4fp5g==}
'@eslint-react/core@2.9.4':
resolution: {integrity: sha512-Ob+Dip1vyR9ch9XL7LUAsGXc0UUf9Kuzn9BEiwOLT7l+cF91ieKeCvIzNPp0LmTuanPfQweJ9iDT9i295SqBZA==}
engines: {node: '>=20.19.0'}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@eslint-react/eff@2.8.1':
resolution: {integrity: sha512-ZASOs8oTZJSiu1giue7V87GEKQvlKLfGfLppal6Rl+aKnfIEz+vartmjpH12pkFQZ9ESRyHzYbU533S6pEDoNg==}
'@eslint-react/eff@2.9.4':
resolution: {integrity: sha512-7AOmozmfa0HgXY9O+J+iX3ciZfViz+W+jhRe2y0YqqkDR7PwV2huzhk/Bxq6sRzzf2uFHqoh/AQNZUhRJ3A05A==}
engines: {node: '>=20.19.0'}
'@eslint-react/eslint-plugin@2.8.1':
resolution: {integrity: sha512-ob+SSDnTPnA5dhiWWJLfyHRLEzWnjilCsohgo5s9PPKF5b5bjxG+c/rwqhQwT3M9Ey83mGNdkrLzt00SOfr4pw==}
'@eslint-react/eslint-plugin@2.9.4':
resolution: {integrity: sha512-B1LOEUBuT4L7EmY3E9F7+K8Jdr9nAzx66USz4uWEtg8ZMn82E2O5TzOBPw6eeL0O9BoyLBoslZotXNQVazR2dA==}
engines: {node: '>=20.19.0'}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@eslint-react/shared@2.8.1':
resolution: {integrity: sha512-NDmJBiMiPDXR6qeZzYOtiILHxWjYwBHxquQ/bMQkWcWK+1qF5LeD8UTRcWtBpZoMPi3sNBWwR3k2Sc5HWZpJ7g==}
'@eslint-react/shared@2.9.4':
resolution: {integrity: sha512-PU7C4JzDZ6OffAWD+HwJdvzGSho25UPYJRyb4wZ/pDaI8QPTDj8AtKWKK69SEOQl2ic89ht1upjQX+jrXhN15w==}
engines: {node: '>=20.19.0'}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@eslint-react/var@2.8.1':
resolution: {integrity: sha512-iHIdEBz6kgW4dEFdhEjpy9SEQ6+d4RYg+WBzHg5J5ktT2xSQFi77Dq6Wtemik6QvvAPnYLRseQxgW+m+1rQlfA==}
'@eslint-react/var@2.9.4':
resolution: {integrity: sha512-Qiih6hT+D2vZmCbAGUooReKlqXjtb/g3SzYj2zNlci6YcWxsQB/pqhR0ayU2AOdW6U9YdeCCfPIwBBQ4AEpyBA==}
engines: {node: '>=20.19.0'}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@ -1208,6 +1208,10 @@ packages:
resolution: {integrity: sha512-r18fEAj9uCk+VjzGt2thsbOmychS+4kxI14spVNibUO2vqKX7obOG+ymZljAwuPZl+S3clPGwCwTDtrdqTiY6Q==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
'@eslint/css-tree@3.6.8':
resolution: {integrity: sha512-s0f40zY7dlMp8i0Jf0u6l/aSswS0WRAgkhgETgiCJRcxIWb4S/Sp9uScKHWbkM3BnoFLbJbmOYk5AZUDFVxaLA==}
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
'@eslint/eslintrc@3.3.3':
resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@ -2867,10 +2871,14 @@ packages:
peerDependencies:
solid-js: 1.9.11
'@tanstack/eslint-plugin-query@5.91.3':
resolution: {integrity: sha512-5GMGZMYFK9dOvjpdedjJs4hU40EdPuO2AjzObQzP7eOSsikunCfrXaU3oNGXSsvoU9ve1Z1xQZZuDyPi0C1M7Q==}
'@tanstack/eslint-plugin-query@5.91.4':
resolution: {integrity: sha512-8a+GAeR7oxJ5laNyYBQ6miPK09Hi18o5Oie/jx8zioXODv/AUFLZQecKabPdpQSLmuDXEBPKFh+W5DKbWlahjQ==}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ^5.0.0
peerDependenciesMeta:
typescript:
optional: true
'@tanstack/form-core@1.24.3':
resolution: {integrity: sha512-e+HzSD49NWr4aIqJWtPPzmi+/phBJAP3nSPN8dvxwmJWqAxuB/cH138EcmCFf3+oA7j3BXvwvTY0I+8UweGPjQ==}
@ -3378,6 +3386,11 @@ packages:
'@ungap/structured-clone@1.3.0':
resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
'@valibot/to-json-schema@1.5.0':
resolution: {integrity: sha512-GE7DmSr1C2UCWPiV0upRH6mv0cCPsqYGs819fb6srCS1tWhyXrkGGe+zxUiwzn/L1BOfADH4sNjY/YHCuP8phQ==}
peerDependencies:
valibot: ^1.2.0
'@vitejs/plugin-react@5.1.2':
resolution: {integrity: sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ==}
engines: {node: ^20.19.0 || >=22.12.0}
@ -4443,6 +4456,19 @@ packages:
peerDependencies:
eslint: '*'
eslint-plugin-better-tailwindcss@4.1.1:
resolution: {integrity: sha512-ctw461TGJi8iM0P01mNVjSW7jeUAdyUgmrrd59np5/VxqX50nayMbwKZkfmjWpP1PWOqlh4CSMOH/WW6ICWmJw==}
engines: {node: ^20.19.0 || ^22.12.0 || >=23.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
oxlint: ^1.35.0
tailwindcss: ^3.3.0 || ^4.1.17
peerDependenciesMeta:
eslint:
optional: true
oxlint:
optional: true
eslint-plugin-command@3.4.0:
resolution: {integrity: sha512-EW4eg/a7TKEhG0s5IEti72kh3YOTlnhfFNuctq5WnB1fst37/IHTd5OkD+vnlRf3opTvUcSRihAateP6bT5ZcA==}
peerDependencies:
@ -4493,15 +4519,15 @@ packages:
peerDependencies:
eslint: ^9.0.0
eslint-plugin-react-dom@2.8.1:
resolution: {integrity: sha512-VAVs3cp/0XTxdjTeLePtZVadj+om+N1VNVy7hyzSPACfh5ncAicC0zOIc5MB15KUWCj8PoG/ZnVny0YqeubgRg==}
eslint-plugin-react-dom@2.9.4:
resolution: {integrity: sha512-lRa3iN082cX3HRKdbKSESmlj+z4zMR10DughwagV7h+IOd3O07UGnYQhenH08GMSyLy1f2D6QJmKBLGbx2p20g==}
engines: {node: '>=20.19.0'}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
eslint-plugin-react-hooks-extra@2.8.1:
resolution: {integrity: sha512-YeZLGzcib6UxlY7Gf+3zz8Mfl7u+OoVj3MukGaTuU6zkm1XQMI8/k4o16bKHuWtUauhn7Udl1bLAWfLgQM5UFw==}
eslint-plugin-react-hooks-extra@2.9.4:
resolution: {integrity: sha512-8hQArFHpXubT+i++8TwIL24vQ5b/ZcnVT3EFOSvy1TdBZw8NqrcFNBVqywQ6YUWX0utuPiTQgeJB0qnBF7gx4g==}
engines: {node: '>=20.19.0'}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@ -4513,27 +4539,34 @@ packages:
peerDependencies:
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0
eslint-plugin-react-naming-convention@2.8.1:
resolution: {integrity: sha512-fVj+hSzIe2I6HyPTf1nccMBXq72c4jbM3gk0T+szo/wewEF8/LgenjfquJoxHPpheb1fujFgdlo5HBhsilAX7Q==}
eslint-plugin-react-naming-convention@2.9.4:
resolution: {integrity: sha512-Ow9ikJ49tDjeTaO2wfUYlSlVBsbG8AZVqoVFu4HH69FZe6I5LEdjZf/gdXnN2W+/JAy7Ru5vYQ8H8LU3tTZERg==}
engines: {node: '>=20.19.0'}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
eslint-plugin-react-refresh@0.4.26:
resolution: {integrity: sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==}
eslint-plugin-react-refresh@0.5.0:
resolution: {integrity: sha512-ZYvmh7VfVgqR/7wR71I3Zl6hK/C5CcxdWYKZSpHawS5JCNgE4efhQWg/+/WPpgGAp9Ngp/rRZYyaIwmPQBq/lA==}
peerDependencies:
eslint: '>=8.40'
eslint: '>=9'
eslint-plugin-react-web-api@2.8.1:
resolution: {integrity: sha512-NYsZKW1aJZ2XZuYTPzbwYLShvGcuXKRV/5TW61VO56gik/btil4Snt5UtyxshHbvT/zXx/Z+QsHul51/XM4/Qw==}
eslint-plugin-react-rsc@2.9.4:
resolution: {integrity: sha512-RwBYSLkcGXQV6SQYABdHLrafUmpfdPBYsAa/kvg6smqEn+/vPKSk0I+uAuzkmiw4y4KXW94Q9rlIdJlzOMdJfQ==}
engines: {node: '>=20.19.0'}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
eslint-plugin-react-x@2.8.1:
resolution: {integrity: sha512-4IpCMrsb63AVEa9diOApIm+T3wUGIzK+EB5vyYocO31YYPJ16+R7Fh4lV3S3fOuX1+aQ+Ad4SE0cYuZ2pF2Tlg==}
eslint-plugin-react-web-api@2.9.4:
resolution: {integrity: sha512-/k++qhGoYtMNZrsQT+M08fCGi/VurL1fE/LNiz2fMwOIU7KjXD9N0kGWPFdIAISnYXGzOg53O5WW/mnNR78emQ==}
engines: {node: '>=20.19.0'}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
eslint-plugin-react-x@2.9.4:
resolution: {integrity: sha512-a078MHeM/FdjRu3KJsFX+PCHewZyC77EjAO7QstL/vvwjsFae3PCWMZ8Q4b+mzUsT4FkFxi5mEW43ZHksPWDFw==}
engines: {node: '>=20.19.0'}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@ -4550,17 +4583,11 @@ packages:
peerDependencies:
eslint: ^8.0.0 || ^9.0.0
eslint-plugin-storybook@10.2.1:
resolution: {integrity: sha512-5+V+dlzTuZfNKUD8hPbLvCVtggcWfI2lDGTpiq0AENrHeAgcztj17wwDva96lbg/sAG20uX71l8HQo3s/GmpHw==}
eslint-plugin-storybook@10.2.6:
resolution: {integrity: sha512-Ykf0hDS97oJlQel21WG+SYtGnzFkkSfifupJ92NQtMMSMLXsWm4P0x8ZQqu9/EQa+dUkGoj9EWyNmmbB/54uhA==}
peerDependencies:
eslint: '>=8'
storybook: ^10.2.1
eslint-plugin-tailwindcss@3.18.2:
resolution: {integrity: sha512-QbkMLDC/OkkjFQ1iz/5jkMdHfiMu/uwujUHLAJK5iwNHD8RTxVTlsUezE0toTZ6VhybNBsk+gYGPDq2agfeRNA==}
engines: {node: '>=18.12.0'}
peerDependencies:
tailwindcss: ^3.4.0
storybook: ^10.2.6
eslint-plugin-toml@1.0.3:
resolution: {integrity: sha512-GlCBX+R313RvFY2Tj0ZmvzCEv8FDp1z2itvTFTV4bW/Bkbl3xEp9inWNsRWH3SiDUlxo8Pew31ILEp/3J0WxaA==}
@ -5585,6 +5612,9 @@ packages:
mdn-data@2.12.2:
resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==}
mdn-data@2.23.0:
resolution: {integrity: sha512-786vq1+4079JSeu2XdcDjrhi/Ry7BWtjDl9WtGPWLiIHb2T66GvIVflZTBoSNZ5JqTtJGYEVMuFA/lbQlMOyDQ==}
memoize-one@5.2.1:
resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==}
@ -6850,11 +6880,15 @@ packages:
resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==}
engines: {node: '>=20'}
tailwind-merge@2.6.0:
resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==}
tailwind-csstree@0.1.4:
resolution: {integrity: sha512-FzD187HuFIZEyeR7Xy6sJbJll2d4SybS90satC8SKIuaNRC05CxMvdzN7BUsfDQffcnabckRM5OIcfArjsZ0mg==}
engines: {node: '>=18.18'}
tailwindcss@3.4.18:
resolution: {integrity: sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==}
tailwind-merge@2.6.1:
resolution: {integrity: sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ==}
tailwindcss@3.4.19:
resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==}
engines: {node: '>=14.0.0'}
hasBin: true
@ -7003,6 +7037,10 @@ packages:
typescript:
optional: true
tsconfig-paths-webpack-plugin@4.2.0:
resolution: {integrity: sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==}
engines: {node: '>=10.13.0'}
tsconfig-paths@4.2.0:
resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==}
engines: {node: '>=6'}
@ -7171,6 +7209,14 @@ packages:
resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==}
hasBin: true
valibot@1.2.0:
resolution: {integrity: sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==}
peerDependencies:
typescript: '>=5'
peerDependenciesMeta:
typescript:
optional: true
vfile-location@5.0.3:
resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
@ -7694,7 +7740,7 @@ snapshots:
idb: 8.0.3
tslib: 2.8.1
'@antfu/eslint-config@7.2.0(@eslint-react/eslint-plugin@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@16.1.6)(@vue/compiler-sfc@3.5.27)(eslint-plugin-react-hooks@7.0.1(eslint@9.39.2(jiti@1.21.7)))(eslint-plugin-react-refresh@0.4.26(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)(vitest@4.0.17)':
'@antfu/eslint-config@7.2.0(@eslint-react/eslint-plugin@2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@16.1.6)(@vue/compiler-sfc@3.5.27)(eslint-plugin-react-hooks@7.0.1(eslint@9.39.2(jiti@1.21.7)))(eslint-plugin-react-refresh@0.5.0(eslint@9.39.2(jiti@1.21.7)))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)(vitest@4.0.17)':
dependencies:
'@antfu/install-pkg': 1.1.0
'@clack/prompts': 0.11.0
@ -7734,10 +7780,10 @@ snapshots:
vue-eslint-parser: 10.2.0(eslint@9.39.2(jiti@1.21.7))
yaml-eslint-parser: 2.0.0
optionalDependencies:
'@eslint-react/eslint-plugin': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eslint-plugin': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@next/eslint-plugin-next': 16.1.6
eslint-plugin-react-hooks: 7.0.1(eslint@9.39.2(jiti@1.21.7))
eslint-plugin-react-refresh: 0.4.26(eslint@9.39.2(jiti@1.21.7))
eslint-plugin-react-refresh: 0.5.0(eslint@9.39.2(jiti@1.21.7))
transitivePeerDependencies:
- '@eslint/json'
- '@vue/compiler-sfc'
@ -8137,9 +8183,9 @@ snapshots:
'@eslint-community/regexpp@4.12.2': {}
'@eslint-react/ast@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)':
'@eslint-react/ast@2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)':
dependencies:
'@eslint-react/eff': 2.8.1
'@eslint-react/eff': 2.9.4
'@typescript-eslint/types': 8.54.0
'@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3)
'@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
@ -8149,12 +8195,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@eslint-react/core@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)':
'@eslint-react/core@2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)':
dependencies:
'@eslint-react/ast': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.8.1
'@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/var': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/ast': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.9.4
'@eslint-react/shared': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/var': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.54.0
'@typescript-eslint/types': 8.54.0
'@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
@ -8164,30 +8210,31 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@eslint-react/eff@2.8.1': {}
'@eslint-react/eff@2.9.4': {}
'@eslint-react/eslint-plugin@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)':
'@eslint-react/eslint-plugin@2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)':
dependencies:
'@eslint-react/eff': 2.8.1
'@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.9.4
'@eslint-react/shared': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.54.0
'@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/types': 8.54.0
'@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint: 9.39.2(jiti@1.21.7)
eslint-plugin-react-dom: 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint-plugin-react-hooks-extra: 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint-plugin-react-naming-convention: 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint-plugin-react-web-api: 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint-plugin-react-x: 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint-plugin-react-dom: 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint-plugin-react-hooks-extra: 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint-plugin-react-naming-convention: 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint-plugin-react-rsc: 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint-plugin-react-web-api: 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint-plugin-react-x: 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
ts-api-utils: 2.4.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@eslint-react/shared@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)':
'@eslint-react/shared@2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)':
dependencies:
'@eslint-react/eff': 2.8.1
'@eslint-react/eff': 2.9.4
'@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint: 9.39.2(jiti@1.21.7)
ts-pattern: 5.9.0
@ -8196,11 +8243,11 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@eslint-react/var@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)':
'@eslint-react/var@2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)':
dependencies:
'@eslint-react/ast': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.8.1
'@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/ast': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.9.4
'@eslint-react/shared': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.54.0
'@typescript-eslint/types': 8.54.0
'@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
@ -8258,6 +8305,11 @@ snapshots:
dependencies:
'@types/json-schema': 7.0.15
'@eslint/css-tree@3.6.8':
dependencies:
mdn-data: 2.23.0
source-map-js: 1.2.1
'@eslint/eslintrc@3.3.3':
dependencies:
ajv: 6.12.6
@ -9902,10 +9954,10 @@ snapshots:
dependencies:
'@swc/counter': 0.1.3
'@tailwindcss/typography@0.5.19(tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.2))':
'@tailwindcss/typography@0.5.19(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2))':
dependencies:
postcss-selector-parser: 6.0.10
tailwindcss: 3.4.18(tsx@4.21.0)(yaml@2.8.2)
tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.2)
'@tanstack/devtools-client@0.0.5':
dependencies:
@ -9957,13 +10009,14 @@ snapshots:
- csstype
- utf-8-validate
'@tanstack/eslint-plugin-query@5.91.3(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)':
'@tanstack/eslint-plugin-query@5.91.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)':
dependencies:
'@typescript-eslint/utils': 8.53.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint: 9.39.2(jiti@1.21.7)
optionalDependencies:
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
- typescript
'@tanstack/form-core@1.24.3':
dependencies:
@ -10593,6 +10646,10 @@ snapshots:
'@ungap/structured-clone@1.3.0': {}
'@valibot/to-json-schema@1.5.0(valibot@1.2.0(typescript@5.9.3))':
dependencies:
valibot: 1.2.0(typescript@5.9.3)
'@vitejs/plugin-react@5.1.2(vite@7.3.1(@types/node@18.15.0)(jiti@1.21.7)(sass@1.93.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))':
dependencies:
'@babel/core': 7.28.6
@ -11747,6 +11804,22 @@ snapshots:
dependencies:
eslint: 9.39.2(jiti@1.21.7)
eslint-plugin-better-tailwindcss@4.1.1(eslint@9.39.2(jiti@1.21.7))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2))(typescript@5.9.3):
dependencies:
'@eslint/css-tree': 3.6.8
'@valibot/to-json-schema': 1.5.0(valibot@1.2.0(typescript@5.9.3))
enhanced-resolve: 5.18.4
jiti: 2.6.1
synckit: 0.11.12
tailwind-csstree: 0.1.4
tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.2)
tsconfig-paths-webpack-plugin: 4.2.0
valibot: 1.2.0(typescript@5.9.3)
optionalDependencies:
eslint: 9.39.2(jiti@1.21.7)
transitivePeerDependencies:
- typescript
eslint-plugin-command@3.4.0(eslint@9.39.2(jiti@1.21.7)):
dependencies:
'@es-joy/jsdoccomment': 0.78.0
@ -11835,37 +11908,35 @@ snapshots:
yaml: 2.8.2
yaml-eslint-parser: 2.0.0
eslint-plugin-react-dom@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
eslint-plugin-react-dom@2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
dependencies:
'@eslint-react/ast': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/core': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.8.1
'@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/var': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/ast': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/core': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.9.4
'@eslint-react/shared': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/var': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.54.0
'@typescript-eslint/types': 8.54.0
'@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
compare-versions: 6.1.1
eslint: 9.39.2(jiti@1.21.7)
string-ts: 2.3.1
ts-pattern: 5.9.0
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
eslint-plugin-react-hooks-extra@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
eslint-plugin-react-hooks-extra@2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
dependencies:
'@eslint-react/ast': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/core': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.8.1
'@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/var': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/ast': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/core': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.9.4
'@eslint-react/shared': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/var': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.54.0
'@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/types': 8.54.0
'@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint: 9.39.2(jiti@1.21.7)
string-ts: 2.3.1
ts-pattern: 5.9.0
typescript: 5.9.3
transitivePeerDependencies:
@ -11882,13 +11953,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-plugin-react-naming-convention@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
eslint-plugin-react-naming-convention@2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
dependencies:
'@eslint-react/ast': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/core': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.8.1
'@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/var': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/ast': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/core': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.9.4
'@eslint-react/shared': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/var': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.54.0
'@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/types': 8.54.0
@ -11901,35 +11972,47 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-plugin-react-refresh@0.4.26(eslint@9.39.2(jiti@1.21.7)):
eslint-plugin-react-refresh@0.5.0(eslint@9.39.2(jiti@1.21.7)):
dependencies:
eslint: 9.39.2(jiti@1.21.7)
eslint-plugin-react-web-api@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
eslint-plugin-react-rsc@2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
dependencies:
'@eslint-react/ast': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/core': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.8.1
'@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/var': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.54.0
'@eslint-react/ast': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/shared': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/var': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/types': 8.54.0
'@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
birecord: 0.1.1
eslint: 9.39.2(jiti@1.21.7)
string-ts: 2.3.1
ts-pattern: 5.9.0
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
eslint-plugin-react-x@2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
eslint-plugin-react-web-api@2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
dependencies:
'@eslint-react/ast': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/core': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.8.1
'@eslint-react/shared': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/var': 2.8.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/ast': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/core': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.9.4
'@eslint-react/shared': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/var': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.54.0
'@typescript-eslint/types': 8.54.0
'@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
birecord: 0.1.1
eslint: 9.39.2(jiti@1.21.7)
ts-pattern: 5.9.0
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
eslint-plugin-react-x@2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3):
dependencies:
'@eslint-react/ast': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/core': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/eff': 2.9.4
'@eslint-react/shared': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@eslint-react/var': 2.9.4(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.54.0
'@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/types': 8.54.0
@ -11937,7 +12020,6 @@ snapshots:
compare-versions: 6.1.1
eslint: 9.39.2(jiti@1.21.7)
is-immutable-type: 5.0.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
string-ts: 2.3.1
ts-api-utils: 2.4.0(typescript@5.9.3)
ts-pattern: 5.9.0
typescript: 5.9.3
@ -11969,21 +12051,15 @@ snapshots:
semver: 7.7.3
typescript: 5.9.3
eslint-plugin-storybook@10.2.1(eslint@9.39.2(jiti@1.21.7))(storybook@10.2.0(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3):
eslint-plugin-storybook@10.2.6(eslint@9.39.2(jiti@1.21.7))(storybook@10.2.0(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3):
dependencies:
'@typescript-eslint/utils': 8.53.1(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)
eslint: 9.39.2(jiti@1.21.7)
storybook: 10.2.0(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
transitivePeerDependencies:
- supports-color
- typescript
eslint-plugin-tailwindcss@3.18.2(tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.2)):
dependencies:
fast-glob: 3.3.3
postcss: 8.5.6
tailwindcss: 3.4.18(tsx@4.21.0)(yaml@2.8.2)
eslint-plugin-toml@1.0.3(eslint@9.39.2(jiti@1.21.7)):
dependencies:
'@eslint/core': 1.0.1
@ -13250,6 +13326,8 @@ snapshots:
mdn-data@2.12.2: {}
mdn-data@2.23.0: {}
memoize-one@5.2.1: {}
merge-stream@2.0.0: {}
@ -14863,9 +14941,11 @@ snapshots:
tagged-tag@1.0.0: {}
tailwind-merge@2.6.0: {}
tailwind-csstree@0.1.4: {}
tailwindcss@3.4.18(tsx@4.21.0)(yaml@2.8.2):
tailwind-merge@2.6.1: {}
tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2):
dependencies:
'@alloc/quick-lru': 5.2.0
arg: 5.0.2
@ -15020,6 +15100,13 @@ snapshots:
optionalDependencies:
typescript: 5.9.3
tsconfig-paths-webpack-plugin@4.2.0:
dependencies:
chalk: 4.1.2
enhanced-resolve: 5.18.4
tapable: 2.3.0
tsconfig-paths: 4.2.0
tsconfig-paths@4.2.0:
dependencies:
json5: 2.2.3
@ -15185,6 +15272,10 @@ snapshots:
uuid@11.1.0: {}
valibot@1.2.0(typescript@5.9.3):
optionalDependencies:
typescript: 5.9.3
vfile-location@5.0.3:
dependencies:
'@types/unist': 3.0.3

View File

@ -1,157 +0,0 @@
/**
* Test suite for the classnames utility function
* This utility combines the classnames library with tailwind-merge
* to handle conditional CSS classes and merge conflicting Tailwind classes
*/
import { cn } from './classnames'
describe('classnames', () => {
/**
* Tests basic classnames library features:
* - String concatenation
* - Array handling
* - Falsy value filtering
* - Object-based conditional classes
*/
it('classnames libs feature', () => {
expect(cn('foo')).toBe('foo')
expect(cn('foo', 'bar')).toBe('foo bar')
expect(cn(['foo', 'bar'])).toBe('foo bar')
expect(cn(undefined)).toBe('')
expect(cn(null)).toBe('')
expect(cn(false)).toBe('')
expect(cn({
foo: true,
bar: false,
baz: true,
})).toBe('foo baz')
})
/**
* Tests tailwind-merge functionality:
* - Conflicting class resolution (last one wins)
* - Modifier handling (hover, focus, etc.)
* - Important prefix (!)
* - Custom color classes
* - Arbitrary values
*/
it('tailwind-merge', () => {
/* eslint-disable tailwindcss/classnames-order */
expect(cn('p-0')).toBe('p-0')
expect(cn('text-right text-center text-left')).toBe('text-left')
expect(cn('pl-4 p-8')).toBe('p-8')
expect(cn('m-[2px] m-[4px]')).toBe('m-[4px]')
expect(cn('m-1 m-[4px]')).toBe('m-[4px]')
expect(cn('overflow-x-auto hover:overflow-x-hidden overflow-x-scroll')).toBe(
'hover:overflow-x-hidden overflow-x-scroll',
)
expect(cn('h-10 h-min')).toBe('h-min')
expect(cn('bg-grey-5 bg-hotpink')).toBe('bg-hotpink')
expect(cn('hover:block hover:inline')).toBe('hover:inline')
expect(cn('font-medium !font-bold')).toBe('font-medium !font-bold')
expect(cn('!font-medium !font-bold')).toBe('!font-bold')
expect(cn('text-gray-100 text-primary-200')).toBe('text-primary-200')
expect(cn('text-some-unknown-color text-components-input-bg-disabled text-primary-200')).toBe('text-primary-200')
expect(cn('bg-some-unknown-color bg-components-input-bg-disabled bg-primary-200')).toBe('bg-primary-200')
expect(cn('border-t border-white/10')).toBe('border-t border-white/10')
expect(cn('border-t border-white')).toBe('border-t border-white')
expect(cn('text-3.5xl text-black')).toBe('text-3.5xl text-black')
})
/**
* Tests the integration of classnames and tailwind-merge:
* - Object-based conditional classes with Tailwind conflict resolution
*/
it('classnames combined with tailwind-merge', () => {
expect(cn('text-right', {
'text-center': true,
})).toBe('text-center')
expect(cn('text-right', {
'text-center': false,
})).toBe('text-right')
})
/**
* Tests handling of multiple mixed argument types:
* - Strings, arrays, and objects in a single call
* - Tailwind merge working across different argument types
*/
it('multiple mixed argument types', () => {
expect(cn('foo', ['bar', 'baz'], { qux: true, quux: false })).toBe('foo bar baz qux')
expect(cn('p-4', ['p-2', 'm-4'], { 'text-left': true, 'text-right': true })).toBe('p-2 m-4 text-right')
})
/**
* Tests nested array handling:
* - Deep array flattening
* - Tailwind merge with nested structures
*/
it('nested arrays', () => {
expect(cn(['foo', ['bar', 'baz']])).toBe('foo bar baz')
expect(cn(['p-4', ['p-2', 'text-center']])).toBe('p-2 text-center')
})
/**
* Tests empty input handling:
* - Empty strings, arrays, and objects
* - Mixed empty and non-empty values
*/
it('empty inputs', () => {
expect(cn('')).toBe('')
expect(cn([])).toBe('')
expect(cn({})).toBe('')
expect(cn('', [], {})).toBe('')
expect(cn('foo', '', 'bar')).toBe('foo bar')
})
/**
* Tests number input handling:
* - Truthy numbers converted to strings
* - Zero treated as falsy
*/
it('numbers as inputs', () => {
expect(cn(1)).toBe('1')
expect(cn(0)).toBe('')
expect(cn('foo', 1, 'bar')).toBe('foo 1 bar')
})
/**
* Tests multiple object arguments:
* - Object merging
* - Tailwind conflict resolution across objects
*/
it('multiple objects', () => {
expect(cn({ foo: true }, { bar: true })).toBe('foo bar')
expect(cn({ foo: true, bar: false }, { bar: true, baz: true })).toBe('foo bar baz')
expect(cn({ 'p-4': true }, { 'p-2': true })).toBe('p-2')
})
/**
* Tests complex edge cases:
* - Mixed falsy values
* - Nested arrays with falsy values
* - Multiple conflicting Tailwind classes
*/
it('complex edge cases', () => {
expect(cn('foo', null, undefined, false, 'bar', 0, 1, '')).toBe('foo bar 1')
expect(cn(['foo', null, ['bar', undefined, 'baz']])).toBe('foo bar baz')
expect(cn('text-sm', { 'text-lg': false, 'text-xl': true }, 'text-2xl')).toBe('text-2xl')
})
/**
* Tests important (!) modifier behavior:
* - Important modifiers in objects
* - Conflict resolution with important prefix
*/
it('important modifier with objects', () => {
expect(cn({ '!font-medium': true }, { '!font-bold': true })).toBe('!font-bold')
expect(cn('font-normal', { '!font-bold': true })).toBe('font-normal !font-bold')
})
})