moex-vibe/apps/frontend/.eslintrc.cjs
Sergey Krylov 53659a36b1 feat(design-system): add data components, form/page-state patterns, and frontend integration
- Inputs: TextField, Select, Checkbox
- Surfaces: Surface, Card, Chip, Badge
- Feedback: Alert, Dialog, Skeleton, Progress
- Financial data: DataTable, Metric, Money, PriceChange
- Form & page-state: FormField, FilterBar, EmptyState, ErrorState, LoadingState
- MUI CssVarsProvider -> ThemeProvider deprecation fix
- Inter font bundled via @fontsource/inter
- ESLint no-restricted-imports (warn) for gradual migration
- storybook-static gitignored

All 268 tests pass (157 design-system + 111 frontend)
2026-06-21 09:49:18 +03:00

85 lines
3.2 KiB
JavaScript

const path = require('path');
const src = path.resolve(__dirname, 'src');
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
sourceType: 'module',
ecmaFeatures: { jsx: true },
},
plugins: ['@typescript-eslint/eslint-plugin', 'react', 'react-hooks', 'import', '@conarti/feature-sliced'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
],
root: true,
env: {
browser: true,
es2020: true,
},
settings: {
react: { version: 'detect' },
'import/resolver': {
typescript: {
alwaysTryTypes: true,
project: './tsconfig.json',
},
},
},
ignorePatterns: ['.eslintrc.cjs', 'vite.config.ts', 'vitest.config.ts', 'dist/'],
rules: {
'no-restricted-imports': ['warn', {
paths: [{
name: '@mui/material',
message: 'Import from @moex-vibe/design-system instead.',
}],
}],
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'@typescript-eslint/no-explicit-any': 'off',
'react/react-in-jsx-scope': 'off',
// FSD layer boundaries (from @conarti/eslint-plugin-feature-sliced)
// layers-slices: catches cross-layer violations (e.g., shared→entities)
'@conarti/feature-sliced/layers-slices': ['error', {
// allow test files and test utilities to import from any layer for mocking
ignoreInFilesPatterns: ['**/*.test.ts', '**/*.test.tsx', '**/*.spec.ts', '**/*.spec.tsx', '**/test/**'],
}],
// absolute-relative: false positives with @/ alias convention — disabled
'@conarti/feature-sliced/absolute-relative': 'off',
// public-api: too strict for app/ and test internals — disabled
'@conarti/feature-sliced/public-api': 'off',
// FSD layer boundaries (from import/no-restricted-paths)
// NOTE: `from` = what's being imported, `target` = the file doing the import
'import/no-restricted-paths': [
'error',
{
zones: [
// shared/ cannot import from entities/, features/, widgets/, pages/, app/
{ from: `${src}/entities`, target: `${src}/shared` },
{ from: `${src}/features`, target: `${src}/shared` },
{ from: `${src}/widgets`, target: `${src}/shared` },
{ from: `${src}/pages`, target: `${src}/shared` },
{ from: `${src}/app`, target: `${src}/shared` },
// entities/ cannot import from features/, widgets/, pages/, app/
{ from: `${src}/features`, target: `${src}/entities` },
{ from: `${src}/widgets`, target: `${src}/entities` },
{ from: `${src}/pages`, target: `${src}/entities` },
{ from: `${src}/app`, target: `${src}/entities` },
// features/ cannot import from widgets/, pages/, app/
{ from: `${src}/widgets`, target: `${src}/features` },
{ from: `${src}/pages`, target: `${src}/features` },
{ from: `${src}/app`, target: `${src}/features` },
// widgets/ cannot import from pages/, app/
{ from: `${src}/pages`, target: `${src}/widgets` },
{ from: `${src}/app`, target: `${src}/widgets` },
// pages/ cannot import from app/
{ from: `${src}/app`, target: `${src}/pages` },
],
},
],
},
};