- 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)
85 lines
3.2 KiB
JavaScript
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` },
|
|
|
|
],
|
|
},
|
|
],
|
|
},
|
|
};
|