Barazo default frontend
barazo.forum
1import { defineConfig, globalIgnores } from 'eslint/config'
2import nextVitals from 'eslint-config-next/core-web-vitals'
3import nextTs from 'eslint-config-next/typescript'
4import tailwindcss from 'eslint-plugin-better-tailwindcss'
5
6const eslintConfig = defineConfig([
7 ...nextVitals,
8 ...nextTs,
9 // Tailwind CSS correctness rules (v4-compatible)
10 {
11 plugins: { 'better-tailwindcss': tailwindcss },
12 settings: {
13 'better-tailwindcss': {
14 entryPoint: 'src/app/globals.css',
15 },
16 },
17 rules: {
18 // warn only: false positives from tailwindcss-animate and prose classes
19 'better-tailwindcss/no-unknown-classes': 'warn',
20 'better-tailwindcss/no-conflicting-classes': 'error',
21 'better-tailwindcss/no-duplicate-classes': 'warn',
22 },
23 },
24 // Disable Tailwind rules for test files (intentional fake class names)
25 {
26 files: ['**/*.test.ts', '**/*.test.tsx', '**/*.spec.ts', '**/*.spec.tsx'],
27 rules: {
28 'better-tailwindcss/no-unknown-classes': 'off',
29 },
30 },
31 // Configure jsx-a11y rules without redefining the plugin
32 // (eslint-config-next already includes jsx-a11y plugin)
33 {
34 rules: {
35 // Accessibility - strict mode per PRD Section 6
36 'jsx-a11y/alt-text': 'error',
37 'jsx-a11y/anchor-has-content': 'error',
38 'jsx-a11y/anchor-is-valid': 'error',
39 'jsx-a11y/aria-activedescendant-has-tabindex': 'error',
40 'jsx-a11y/aria-props': 'error',
41 'jsx-a11y/aria-proptypes': 'error',
42 'jsx-a11y/aria-role': 'error',
43 'jsx-a11y/aria-unsupported-elements': 'error',
44 'jsx-a11y/autocomplete-valid': 'error',
45 'jsx-a11y/click-events-have-key-events': 'error',
46 'jsx-a11y/control-has-associated-label': 'off',
47 'jsx-a11y/heading-has-content': 'error',
48 'jsx-a11y/html-has-lang': 'error',
49 'jsx-a11y/iframe-has-title': 'error',
50 'jsx-a11y/img-redundant-alt': 'error',
51 'jsx-a11y/interactive-supports-focus': 'error',
52 'jsx-a11y/label-has-associated-control': 'error',
53 'jsx-a11y/media-has-caption': 'error',
54 'jsx-a11y/mouse-events-have-key-events': 'error',
55 'jsx-a11y/no-access-key': 'error',
56 'jsx-a11y/no-autofocus': ['error', { ignoreNonDOM: true }],
57 'jsx-a11y/no-distracting-elements': 'error',
58 'jsx-a11y/no-interactive-element-to-noninteractive-role': 'error',
59 'jsx-a11y/no-noninteractive-element-interactions': 'error',
60 'jsx-a11y/no-noninteractive-element-to-interactive-role': 'error',
61 'jsx-a11y/no-noninteractive-tabindex': 'error',
62 'jsx-a11y/no-redundant-roles': 'error',
63 'jsx-a11y/no-static-element-interactions': 'error',
64 'jsx-a11y/role-has-required-aria-props': 'error',
65 'jsx-a11y/role-supports-aria-props': 'error',
66 'jsx-a11y/scope': 'error',
67 'jsx-a11y/tabindex-no-positive': 'error',
68 },
69 },
70 {
71 rules: {
72 // TypeScript strict per CLAUDE.md
73 '@typescript-eslint/no-explicit-any': 'error',
74 '@typescript-eslint/no-unused-vars': [
75 'error',
76 { argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
77 ],
78 },
79 },
80 // Override default ignores of eslint-config-next.
81 globalIgnores([
82 '.next/**',
83 'dist/**',
84 'out/**',
85 'build/**',
86 'next-env.d.ts',
87 'node_modules/**',
88 'playwright-report/**',
89 'test-results/**',
90 ]),
91])
92
93export default eslintConfig