Files
ermnvldmr.com/eslint.config.mjs
deytenit b3638f4d63 fix: cyrillic fonts, dev certs, page head, and ru-text typography (#67)
🤖 PR generated for branch `fix/cyrillic-fonts-dev-certs-and-page-head`.

### Changes Summary
- **Fonts**: Add Cyrillic glyph subsets for Lato, EB Garamond, and Fira
Code.
- **Dev**: Support remote Root CA and encrypted dev CA key in
`.env.dev`.
- **UI & Kits**: Add size variant to `Breadcrumbs` component and enlarge
`PageHead` breadcrumbs with tuned collapse scroll threshold.
- **ESLint**: Add `no-hanging-particles` i18n & markdown typography rule
with auto-fixer.
- **Content & i18n**: Apply `ru-text` editorial and typography polish
(em dashes, number ranges, «ё» restoration, non-breaking spaces) across
`services/www` and `services/docs`.
2026-10-25 15:21:09 +03:00

141 lines
4.1 KiB
JavaScript

// @ts-check
import { baseConfig } from '@ermnvldmr/eslint-config/dev';
import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
import storybook from 'eslint-plugin-storybook';
import jsxA11y from 'eslint-plugin-jsx-a11y';
import globals from 'globals';
import tseslint from 'typescript-eslint';
export default [
...baseConfig,
// Additional ignores for monorepo
{
ignores: [
'services/docs/public/**',
'services/docs/resources/**',
'services/docs/assets/**',
'services/docs/archetypes/**',
'**/node_modules/**',
'**/dist/**',
'**/build/**',
'**/coverage/**',
'**/storybook-static/**',
'**/.next/**',
'**/*.d.ts',
],
},
// Storybook - recommended configuration for flat config
...storybook.configs['flat/recommended'],
// React - Strict Configuration
{
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
...react.configs.flat.recommended,
languageOptions: {
...react.configs.flat.recommended.languageOptions,
globals: {
...globals.serviceworker,
...globals.browser,
},
},
settings: {
react: {
version: 'detect',
},
},
rules: {
// React specific rules
'react/react-in-jsx-scope': 'off', // Not needed with React 17+
'react/prop-types': 'off', // Using TypeScript instead
'react/display-name': 'error',
'react/no-array-index-key': 'warn',
'react/no-danger': 'error',
'react/no-deprecated': 'error',
'react/no-direct-mutation-state': 'error',
'react/no-find-dom-node': 'error',
'react/no-is-mounted': 'error',
'react/no-render-return-value': 'error',
'react/no-string-refs': 'error',
'react/no-unescaped-entities': 'error',
'react/no-unknown-property': 'error',
'react/no-unsafe': 'error',
'react/self-closing-comp': 'error',
'react/void-dom-elements-no-children': 'error',
// JSX specific rules
'react/jsx-boolean-value': 'error',
'react/jsx-curly-brace-presence': ['error', { props: 'never', children: 'never' }],
'react/jsx-fragments': ['error', 'syntax'],
'react/jsx-no-duplicate-props': 'error',
'react/jsx-no-target-blank': 'error',
'react/jsx-no-useless-fragment': 'error',
'react/jsx-pascal-case': 'error',
'react/jsx-sort-props': [
'error',
{
callbacksLast: true,
shorthandFirst: true,
reservedFirst: true,
},
],
},
},
// React Hooks
{
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
plugins: { 'react-hooks': reactHooks },
rules: {
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'error',
},
},
// React Refresh
{
files: ['**/*.{jsx,tsx}'],
ignores: ['.config/jest/**/*.{jsx,tsx}', '**/test-utils.tsx'],
plugins: { 'react-refresh': reactRefresh },
rules: {
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
},
},
// Accessibility (JSX A11Y)
{
files: ['**/*.{jsx,tsx}'],
...jsxA11y.flatConfigs.recommended,
rules: {
'jsx-a11y/alt-text': 'error',
'jsx-a11y/anchor-has-content': 'error',
'jsx-a11y/anchor-is-valid': 'error',
'jsx-a11y/aria-props': 'error',
'jsx-a11y/aria-proptypes': 'error',
'jsx-a11y/aria-role': 'error',
'jsx-a11y/aria-unsupported-elements': 'error',
'jsx-a11y/click-events-have-key-events': 'error',
'jsx-a11y/heading-has-content': 'error',
'jsx-a11y/html-has-lang': 'error',
'jsx-a11y/img-redundant-alt': 'error',
'jsx-a11y/interactive-supports-focus': 'error',
'jsx-a11y/label-has-associated-control': 'error',
'jsx-a11y/no-autofocus': 'error',
'jsx-a11y/no-distracting-elements': 'error',
'jsx-a11y/no-redundant-roles': 'error',
'jsx-a11y/role-has-required-aria-props': 'error',
'jsx-a11y/role-supports-aria-props': 'error',
},
},
// Set globals for Node scripts.
{
files: ['scripts/**'],
languageOptions: {
globals: globals.node,
},
},
];