Files
blackcanyontickets/reactrebuild0825/eslint.config.js
dzinesco 6d879d0685 feat(theme): finalize design token system with WCAG AA compliance
- Fix gold text contrast in light theme from 3.30:1 to 6.38:1 (AA compliant)
- Separate ThemeContext into definition and provider files for ESLint compliance
- Update contrast report with final validation results (100% passing tests)
- Ensure all accent colors meet WCAG AA standards across light/dark themes
- Complete design token system with proper semantic color roles

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-16 02:21:19 -06:00

396 lines
12 KiB
JavaScript

import js from '@eslint/js';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
import react from 'eslint-plugin-react';
import jsxA11y from 'eslint-plugin-jsx-a11y';
import importPlugin from 'eslint-plugin-import';
import tseslint from 'typescript-eslint';
import prettier from 'eslint-config-prettier';
export default tseslint.config(
{
ignores: [
'dist/**',
'node_modules/**',
'build/**',
'coverage/**',
'public/**',
'*.config.js',
'*.config.ts',
'.vscode/**',
'.git/**',
'qa-screenshots/**',
'claude-logs/**',
],
},
// Configuration for TypeScript files
{
extends: [
js.configs.recommended,
...tseslint.configs.recommended,
...tseslint.configs.strict,
prettier,
],
files: ['**/*.{ts,tsx}'],
languageOptions: {
ecmaVersion: 2023,
sourceType: 'module',
parser: tseslint.parser,
parserOptions: {
ecmaFeatures: {
jsx: true,
},
project: './tsconfig.json',
tsconfigRootDir: import.meta.dirname,
},
globals: {
window: 'readonly',
document: 'readonly',
console: 'readonly',
process: 'readonly',
Buffer: 'readonly',
__dirname: 'readonly',
__filename: 'readonly',
global: 'readonly',
},
},
plugins: {
react: react,
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
'jsx-a11y': jsxA11y,
import: importPlugin,
},
settings: {
react: {
version: 'detect',
},
'import/resolver': {
typescript: {
alwaysTryTypes: true,
project: './tsconfig.json',
},
node: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
},
'import/parsers': {
'@typescript-eslint/parser': ['.ts', '.tsx'],
},
},
rules: {
// React Rules
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
...reactHooks.configs.recommended.rules,
...jsxA11y.configs.recommended.rules,
// React Refresh
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
// React Specific
'react/prop-types': 'off', // Using TypeScript for prop validation
'react/jsx-uses-react': 'off', // Not needed with new JSX transform
'react/react-in-jsx-scope': 'off', // Not needed with new JSX transform
'react/jsx-props-no-spreading': [
'warn',
{
html: 'enforce',
custom: 'ignore',
explicitSpread: 'ignore',
},
],
'react/jsx-key': [
'error',
{
checkFragmentShorthand: true,
checkKeyMustBeforeSpread: true,
warnOnDuplicates: true,
},
],
'react/jsx-no-useless-fragment': ['warn', { allowExpressions: true }],
'react/self-closing-comp': ['warn', { component: true, html: true }],
'react/jsx-boolean-value': ['warn', 'never'],
'react/jsx-curly-brace-presence': [
'warn',
{
props: 'never',
children: 'never',
},
],
'react/jsx-pascal-case': ['error', { allowAllCaps: true }],
'react/no-array-index-key': 'off', // Allow index keys for static lists
'react/no-danger': 'error',
'react/no-deprecated': 'error',
'react/no-unsafe': 'error',
'react/hook-use-state': 'warn',
// TypeScript Rules
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
destructuredArrayIgnorePattern: '^_',
ignoreRestSiblings: true,
},
],
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-non-null-assertion': 'warn', // Sometimes needed for DOM manipulation
'@typescript-eslint/prefer-nullish-coalescing': 'error',
'@typescript-eslint/prefer-optional-chain': 'error',
'@typescript-eslint/no-unnecessary-condition': 'warn',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unused-expressions': 'error',
'@typescript-eslint/prefer-readonly': 'warn',
'@typescript-eslint/explicit-function-return-type': [
'off', // Let TypeScript infer return types for React components
{
allowExpressions: true,
allowTypedFunctionExpressions: true,
allowHigherOrderFunctions: true,
allowDirectConstAssertionInArrowFunctions: true,
},
],
'@typescript-eslint/consistent-type-imports': [
'error',
{ prefer: 'type-imports', fixStyle: 'separate-type-imports' },
],
'@typescript-eslint/consistent-type-exports': 'error',
'@typescript-eslint/method-signature-style': ['error', 'property'],
'@typescript-eslint/array-type': ['error', { default: 'array' }],
'@typescript-eslint/ban-tslint-comment': 'error',
'@typescript-eslint/class-literal-property-style': ['error', 'fields'],
// Import Rules
'import/order': [
'error',
{
groups: [
'builtin',
'external',
'internal',
'parent',
'sibling',
'index',
'type',
],
pathGroups: [
{
pattern: 'react',
group: 'builtin',
position: 'before',
},
{
pattern: 'react-*',
group: 'external',
position: 'before',
},
{
pattern: '@/**',
group: 'internal',
position: 'before',
},
],
pathGroupsExcludedImportTypes: ['react'],
'newlines-between': 'always',
alphabetize: {
order: 'asc',
caseInsensitive: true,
},
},
],
'import/no-unresolved': 'error',
'import/no-unused-modules': 'warn',
'import/no-duplicates': 'error',
'import/no-self-import': 'error',
'import/no-cycle': ['error', { maxDepth: 10 }],
'import/prefer-default-export': 'off',
'import/no-default-export': 'off',
'import/named': 'error',
'import/namespace': 'error',
'import/default': 'off', // React 18 JSX transform doesn't export default
'import/export': 'error',
// General Code Quality
'no-console': ['warn', { allow: ['warn', 'error'] }],
'no-debugger': 'error',
'no-alert': 'error',
'no-var': 'error',
'prefer-template': 'error',
'prefer-arrow-callback': 'error',
'arrow-body-style': ['warn', 'as-needed'],
'object-shorthand': ['error', 'always'],
'no-useless-rename': 'error',
'no-useless-computed-key': 'error',
'no-useless-constructor': 'error',
'no-useless-return': 'error',
'no-nested-ternary': 'off', // Allow nested ternaries for conditional rendering
'no-unneeded-ternary': 'error',
'prefer-destructuring': [
'warn',
{
array: false,
object: true,
},
],
'spaced-comment': ['error', 'always', { markers: ['/'] }],
eqeqeq: ['error', 'always', { null: 'ignore' }],
curly: ['error', 'all'],
'no-else-return': ['error', { allowElseIf: false }],
'no-return-assign': 'error',
'no-return-await': 'error',
'require-await': 'error',
'no-async-promise-executor': 'error',
'no-await-in-loop': 'warn',
// Naming Conventions
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'variable',
format: ['camelCase', 'PascalCase', 'UPPER_CASE'],
leadingUnderscore: 'allow',
},
{
selector: 'function',
format: ['camelCase', 'PascalCase'],
},
{
selector: 'typeLike',
format: ['PascalCase'],
},
{
selector: 'interface',
format: ['PascalCase'],
},
{
selector: 'typeAlias',
format: ['PascalCase'],
},
{
selector: 'enum',
format: ['PascalCase'],
},
],
},
},
// Configuration for JavaScript files
{
extends: [js.configs.recommended, prettier],
files: ['**/*.{js,jsx}'],
languageOptions: {
ecmaVersion: 2023,
sourceType: 'module',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
globals: {
window: 'readonly',
document: 'readonly',
console: 'readonly',
process: 'readonly',
Buffer: 'readonly',
__dirname: 'readonly',
__filename: 'readonly',
global: 'readonly',
},
},
plugins: {
react: react,
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
'jsx-a11y': jsxA11y,
import: importPlugin,
},
settings: {
react: {
version: 'detect',
},
'import/resolver': {
node: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
},
},
rules: {
// React Rules
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
...reactHooks.configs.recommended.rules,
...jsxA11y.configs.recommended.rules,
// React Refresh
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
// React Specific
'react/prop-types': 'off',
'react/jsx-uses-react': 'off',
'react/react-in-jsx-scope': 'off',
'react/jsx-key': [
'error',
{
checkFragmentShorthand: true,
checkKeyMustBeforeSpread: true,
warnOnDuplicates: true,
},
],
'react/jsx-no-useless-fragment': ['warn', { allowExpressions: true }],
'react/self-closing-comp': ['warn', { component: true, html: true }],
'react/jsx-boolean-value': ['warn', 'never'],
'react/jsx-curly-brace-presence': [
'warn',
{
props: 'never',
children: 'never',
},
],
'react/jsx-pascal-case': ['error', { allowAllCaps: true }],
'react/no-array-index-key': 'off', // Allow index keys for static lists
'react/no-danger': 'error',
'react/no-deprecated': 'error',
'react/no-unsafe': 'error',
// General Code Quality
'no-console': ['warn', { allow: ['warn', 'error'] }],
'no-debugger': 'error',
'no-alert': 'error',
'no-var': 'error',
'prefer-template': 'error',
'prefer-arrow-callback': 'error',
'arrow-body-style': ['warn', 'as-needed'],
'object-shorthand': ['error', 'always'],
'no-useless-rename': 'error',
'no-useless-computed-key': 'error',
'no-useless-constructor': 'error',
'no-useless-return': 'error',
'no-nested-ternary': 'off', // Allow nested ternaries for conditional rendering
'no-unneeded-ternary': 'error',
'prefer-destructuring': [
'warn',
{
array: false,
object: true,
},
],
'spaced-comment': ['error', 'always', { markers: ['/'] }],
eqeqeq: ['error', 'always', { null: 'ignore' }],
curly: ['error', 'all'],
'no-else-return': ['error', { allowElseIf: false }],
'no-return-assign': 'error',
'require-await': 'error',
'no-async-promise-executor': 'error',
'no-await-in-loop': 'warn',
},
}
);