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>
This commit is contained in:
395
reactrebuild0825/eslint.config.js
Normal file
395
reactrebuild0825/eslint.config.js
Normal file
@@ -0,0 +1,395 @@
|
||||
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',
|
||||
},
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user