diff --git a/.codeclimate.yml b/.codeclimate.yml index e424352751..e7b2e3b282 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -25,17 +25,13 @@ checks: return-statements: config: threshold: 6 -# similar-code: -# config: -# threshold: 45 -# identical-code: -# config: -# threshold: 45 + similar-code: + config: + threshold: 60 exclude_patterns: - "config/" - "dist/" - - "features/" - "**/node_modules/" - "**/spec/" - "**/test/" @@ -43,4 +39,8 @@ exclude_patterns: - "**/vendor/" - "**/*.d.ts" - "**/*.test.ts" - - "e2e/setup/**/*.ts" + - "e2e/**/*.ts" + + - "packages/eslint-config" + - "packages/eslint-plugin" + - "packages/stylelint-config" diff --git a/.commitlintrc.yml b/.commitlintrc.yml index e5dce4e895..8218d6bf2f 100644 --- a/.commitlintrc.yml +++ b/.commitlintrc.yml @@ -65,6 +65,7 @@ rules: - deps-dev - eslint-plugin - eslint-config + - stylelint-config - e2e - ci # Deprecated scopes: diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index cda609cc67..38daf5b4b1 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -67,4 +67,4 @@ jobs: - name: Install NPM Dependencies run: npm ci - name: Run ESLint Plugin Tests - run: npm run test -w eslint-plugin + run: npm run test -w packages/eslint-plugin diff --git a/.gitignore b/.gitignore index b478c16f15..e0311aec2d 100644 --- a/.gitignore +++ b/.gitignore @@ -11,9 +11,9 @@ node_modules # Build output *.tgz target -site/dist -eslint-plugin/dist +site/dist +e2e/.diff # Generated surces /modules @@ -29,4 +29,3 @@ npm-debug.log # Jest & Sonar /.report /.scannerwork -/e2e/.diff diff --git a/.releaserc.yml b/.releaserc.yml index fbba2579d3..1dec83c8dd 100644 --- a/.releaserc.yml +++ b/.releaserc.yml @@ -68,8 +68,7 @@ plugins: - package.json - package-lock.json - site/package.json - - eslint-config/package.json - - eslint-plugin/package.json + - packages/*/package.json message: "chore(release): ${nextRelease.version} \n\n${nextRelease.notes}" - - "@semantic-release/github" diff --git a/.stylelintrc.yml b/.stylelintrc.yml index 3e213ef169..9d1c64e2ab 100644 --- a/.stylelintrc.yml +++ b/.stylelintrc.yml @@ -1,16 +1,13 @@ plugins: - - stylelint-prettier # Custom plugin to disallow absolute import paths - ./build/import.stylelint.js # Use LESS preprocessor customSyntax: postcss-less -rules: - # Prettier integration - prettier/prettier: - - true - - severity: warning +extends: + - '@exadel/stylelint-config-esl' +rules: # Disallow unknown at-rules at-rule-no-unknown: true # Warn about empty selectors @@ -73,7 +70,7 @@ rules: overrides: # Demo site pages sources - - files: site/**/*.{css,less} + - files: ['site/**/*.{css,less}'] rules: # Warn about duplicate properties within declaration blocks declaration-block-no-duplicate-properties: diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 80d31c0956..8d5dee24f3 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -61,7 +61,7 @@ ESL codebase is written using TypeScript and LESS CSS-preprocessor. ESL uses the following tools to keep codebase quality - ESLint to lint scripts -- Own ESLint shared configuration (see [eslint-config](../eslint-config) sub-package) +- Own ESLint shared configuration (see [eslint-config](../packages/eslint-config) sub-package) - StyleLint to lint styles - Jest to run unit tests - CommitLint to check commit message format @@ -112,15 +112,15 @@ ESL project consists of the following directories: - [🔧 tsconfig.json](../site/tsconfig.json) - TS config for demo pages scripts - [🔧 webpack.config.js](../site/webpack.config.js) - webpack build file for demo pages - -- [📁 eslint-plugin](../eslint-plugin) - sub-package root for ESL ESLint plugin - - [📁 src](../eslint-plugin/src) - ESLint plugin sources - - [📁 test](../eslint-plugin/test) - ESLint plugin tests - -- [📁 eslint-config](../eslint-config) - sub-package root for ESL ESLint shared configuration - - [📁 rules](../eslint-config/rules) - ESLint shared configuration rule sets - - [📄 index.js](../eslint-config/index.js) - ESLint shared configuration main file - +- [📁 packages](../packages) - ESL monorepo sub-packages + - [📁 eslint-plugin](../packages/eslint-plugin) - sub-package root for ESL ESLint plugin + - [📁 src](../packages/eslint-plugin/src) - ESLint plugin sources + - [📁 test](../packages/eslint-plugin/test) - ESLint plugin tests + - [📁 eslint-config](../packages/eslint-config) - sub-package root for ESL ESLint shared configuration + - [📁 rules](../packages/eslint-config/rules) - ESLint shared configuration rule sets + - [📄 index.js](../packages/eslint-config/index.js) - ESLint shared configuration main file + - [📁 stylelint-config](../packages/stylelint-config) - sub-package root for ESL StyleLint shared configuration + - [📄 index.js](../packages/stylelint-config/index.js) - StyleLint shared configuration main file - [📁 build](../build) - library common build scripts - [📁 linting](../linting) - ES Lint rule-sets diff --git a/eslint-config/index.js b/eslint-config/index.js deleted file mode 100644 index e97e8c1a33..0000000000 --- a/eslint-config/index.js +++ /dev/null @@ -1,37 +0,0 @@ -/** Default TS Configuration */ -module.exports.typescript = require('./rules/eslint.config.language'); - -/** Shared plugins */ -module.exports.plugins = { - get '@stylistic' () { - return require('@stylistic/eslint-plugin') - }, - get 'editorconfig'() { - return require('eslint-plugin-editorconfig'); - }, - get 'import'() { - return require('eslint-plugin-import-x'); - }, - get 'tsdoc'() { - return require('eslint-plugin-tsdoc'); - }, - get 'sonarjs'() { - return require('eslint-plugin-sonarjs'); - }, - get 'typescript-eslint' () { - return require('typescript-eslint') - } -}; - -/** Default ESLint Configuration */ -module.exports.recommended = [ - ...require('./rules/eslint.config.codestyle'), - ...require('./rules/eslint.config.coderules'), - ...require('./rules/eslint.config.sonarjs'), - ...require('./rules/eslint.config.stylistic'), - ...require('./rules/eslint.config.editorconfig'), - ...require('./rules/eslint.config.import'), - ...require('./rules/eslint.config.tsdoc') -]; - -// TODO: Separate ES / TS builder diff --git a/eslint-config/rules/eslint.config.codestyle.js b/eslint-config/rules/eslint.config.codestyle.js deleted file mode 100644 index a668283222..0000000000 --- a/eslint-config/rules/eslint.config.codestyle.js +++ /dev/null @@ -1,139 +0,0 @@ -const eslint = require('@eslint/js'); -const tseslint = require('typescript-eslint'); - -module.exports = [ - eslint.configs.recommended, - ...tseslint.configs.recommended, - { - plugins: { - eslint, - '@typescript-eslint': tseslint.plugin, - }, - rules: { - // Enforces naming conventions for everything across a codebase - // TODO: configure - // '@typescript-eslint/naming-convention': [ - // warn, { - // selector: variable, - // format: [ camelCase, PascalCase, UPPER_CASE ], - // leadingUnderscore: allow - // } - // ] - - // Limit Cyclomatic Complexity - 'complexity': 'warn', - - // Require following curly brace conventions - 'curly': ['warn', 'multi-line'], - - // Max 3 classes per file (ideally 1 per file) - 'max-classes-per-file': ['warn', 3], - - // Warn about empty block statements - 'no-empty': 'warn', - - // Underscores allowed due to 'private-member' notation - 'no-underscore-dangle': 'off', - - // 'var' declaration operator is not allowed - 'no-var': 'error', - - // Warn to prefer shorthand object keys - 'object-shorthand': 'warn', - - // Disallow multiple declaration per one line or declaration operator - 'one-var': ['error', 'never'], - - // Using of arrow functions is optional - 'prefer-arrow-callback': 'off', - - // Prefer const declaration operator - 'prefer-const': 'error', - - // Limit max lines count per file to 500 - 'max-lines': ['warn', 500], - - // Do not enforce dot notation whenever possible - 'dot-notation': 'off', - '@typescript-eslint/dot-notation': 'off', - - // Prefers consistent usage of type assertions - '@typescript-eslint/consistent-type-assertions': 'warn', - - // Require the use of the namespace keyword instead of the module keyword to declare custom TypeScript modules - '@typescript-eslint/prefer-namespace-keyword': 'warn', - - // Allows initialization in variable declarations - 'init-declarations': 'off', - '@typescript-eslint/init-declarations': 'off', - - // Warn about duplicate class members - 'no-dupe-class-members': 'off', - '@typescript-eslint/no-dupe-class-members': 'warn', - - // The use of eval()-like methods is not recommended - 'no-eval': 'off', - 'no-implied-eval': 'off', - '@typescript-eslint/no-implied-eval': 'warn', - - // Allows this keywords outside of classes or class-like objects - 'no-invalid-this': 'off', - '@typescript-eslint/no-invalid-this': 'off', - - // Warn about function declarations that contain unsafe references inside loop statements - 'no-loop-func': 'off', - '@typescript-eslint/no-loop-func': 'warn', - - // Warn about literal numbers that lose precision - 'no-loss-of-precision': 'off', - '@typescript-eslint/no-loss-of-precision': 'warn', - - // Disallow variable redeclaration - 'no-redeclare': 'off', - '@typescript-eslint/no-redeclare': 'error', - - // Warn about variable declarations that are shadowing variables declared in the outer scope - 'no-shadow': 'off', - '@typescript-eslint/no-shadow': 'warn', - - // Warn about throwing literals as exceptions - 'only-throw-error': 'off', - '@typescript-eslint/only-throw-error': 'warn', - - // Allows unused expressions - 'no-unused-expressions': 'off', - '@typescript-eslint/no-unused-expressions': 'off', - - // Warn about unused variables - 'no-unused-vars': 'off', - '@typescript-eslint/no-unused-vars': [ - 'warn', - { - vars: 'all', caughtErrors: 'none', args: 'none' - } - ], - - // Warn about unnecessary constructors - 'no-useless-constructor': 'off', - '@typescript-eslint/no-useless-constructor': 'warn', - - // Do not warn if an async function has no await expression - 'require-await': 'off', - '@typescript-eslint/require-await': 'off', - - // Prefers consistent returning of awaited values - 'return-await': 'off', - '@typescript-eslint/return-await': 'warn', - - // No spread preferences in bounds of the library - 'prefer-spread': 'off' - } - }, - { - files: ["**/*.test.ts", "**/*.spec.ts"], - rules: { - // no class count limit for tests - 'max-classes-per-file': "off" - } - } -] diff --git a/eslint-config/rules/eslint.config.editorconfig.js b/eslint-config/rules/eslint.config.editorconfig.js deleted file mode 100644 index befd774391..0000000000 --- a/eslint-config/rules/eslint.config.editorconfig.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = [ - { - plugins: { - editorconfig: require('eslint-plugin-editorconfig') - }, - rules: { - // Enforce charset check - 'editorconfig/charset': "warn", - // Enforce EOL for all files - 'editorconfig/eol-last': "warn", - // Require no trailing spaces - 'editorconfig/no-trailing-spaces': "warn" - } - } -]; diff --git a/eslint-config/rules/eslint.config.language.js b/eslint-config/rules/eslint.config.language.js deleted file mode 100644 index 4cea29a006..0000000000 --- a/eslint-config/rules/eslint.config.language.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = [ - { - languageOptions: { - ecmaVersion: 2017, - sourceType: "module", - parser: require('typescript-eslint').parser, - parserOptions: { - projectService: true - } - } - } -] diff --git a/eslint-config/rules/eslint.config.tsdoc.js b/eslint-config/rules/eslint.config.tsdoc.js deleted file mode 100644 index 918e2bfaf3..0000000000 --- a/eslint-config/rules/eslint.config.tsdoc.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = [ - { - plugins: { - tsdoc: require('eslint-plugin-tsdoc') - }, - rules: { - // Enable TS Doc syntax check - 'tsdoc/syntax': "warn" - } - } -]; diff --git a/eslint.config.ignore.js b/eslint.config.ignore.mjs similarity index 80% rename from eslint.config.ignore.js rename to eslint.config.ignore.mjs index ae711049d0..2fa077b502 100644 --- a/eslint.config.ignore.js +++ b/eslint.config.ignore.mjs @@ -1,4 +1,4 @@ -module.exports = [ +export default [ { ignores: [ // Common configuration @@ -15,13 +15,13 @@ module.exports = [ '/polyfills/**', // Site output '/site/dist/**', - // ESL ESLint Plugin output - '/eslint-plugin/dist/**', + // ESL ESLint Plugin files + '/packages/eslint-plugin/**', // ESL ESLint Config files - '/eslint-config/**', + '/packages/eslint-config/**', // E2E tests commons 'e2e/reporters/**', 'e2e/transformer/**', ] } -] +]; diff --git a/eslint.config.js b/eslint.config.js deleted file mode 100644 index 2cea061be2..0000000000 --- a/eslint.config.js +++ /dev/null @@ -1,35 +0,0 @@ -module.exports = [ - { - files: ["**/*.ts", "**/*.tsx"], - linterOptions: { - reportUnusedDisableDirectives: "warn" - } - }, - ...require('./eslint.config.ignore'), - - // Using shared ESL ESLint Config - ...require('@exadel/eslint-config-esl').typescript, - ...require('@exadel/eslint-config-esl').recommended, - - // ESL ESLint Plugin - ...require('@exadel/eslint-plugin-esl').recommended, - - // Overrides - { - files: ["**/polyfills/**/*.ts"], - rules: { - 'no-new-wrappers': "off" - } - }, - { - files: ["site/**/*.ts"], - rules: { - 'no-restricted-imports': ["error", { - "patterns": [{ - "group": ["../../**/modules/**", "../../**/polyfills/**"], - 'message': "Do not import from src/modules directly. Use the `@exadel/esl` package resolved by NPM workspaces instead." - }] - }] - } - } -]; diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000000..fcbee259d0 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,39 @@ +import {lang, strict} from '@exadel/eslint-config-esl'; +import {recommended as eslRecommended} from '@exadel/eslint-plugin-esl'; +import eslintConfigIgnore from './eslint.config.ignore.mjs'; + +export default [ + { + files: ['**/*.ts', '**/*.tsx'], + linterOptions: { + reportUnusedDisableDirectives: 'warn' + } + }, + ...eslintConfigIgnore, + + // Using shared ESL ESLint Config + ...lang, + ...strict, + + // ESL ESLint Plugin + ...eslRecommended, + + // Overrides + { + files: ['**/polyfills/**/*.ts'], + rules: { + 'no-new-wrappers': 'off' + } + }, + { + files: ['site/**/*.ts'], + rules: { + 'no-restricted-imports': ['error', { + 'patterns': [{ + 'group': ['../../**/modules/**', '../../**/polyfills/**'], + 'message': 'Do not import from src/modules directly. Use the `@exadel/esl` package resolved by NPM workspaces instead.' + }] + }] + } + } +]; diff --git a/package-lock.json b/package-lock.json index b88cc03776..261fed1116 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,9 @@ "version": "5.0.1", "license": "MIT", "workspaces": [ + "packages/*", "e2e", - "site", - "eslint-config", - "eslint-plugin" + "site" ], "dependencies": { "@types/video.js": "7.3.58", @@ -23,6 +22,7 @@ "@commitlint/config-conventional": "^19.7.1", "@exadel/eslint-config-esl": "file:eslint-config", "@exadel/eslint-plugin-esl": "file:eslint-plugin", + "@exadel/stylelint-config-esl": "file:stylelint-config", "@semantic-release/changelog": "^6.0.3", "@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/git": "^10.0.1", @@ -42,14 +42,12 @@ "kleur": "^4.1.5", "less": "^4.2.2", "lint-staged": "^15.4.3", - "postcss": "^8.5.2", + "postcss": "^8.5.3", "postcss-less": "^6.0.0", - "prettier": "^3.5.0", "rimraf": "^6.0.1", "semantic-release": "^24.2.3", "smoothscroll-polyfill": "^0.4.4", - "stylelint": "^16.14.1", - "stylelint-prettier": "^5.0.3", + "stylelint": "^16.15.0", "ts-jest": "^29.2.6", "typescript": "5.7.3" } @@ -76,14 +74,16 @@ "eslint-config": { "name": "@exadel/eslint-config-esl", "version": "5.0.1", + "extraneous": true, "license": "MIT", "dependencies": { "@eslint/js": "^9.21.0", - "@stylistic/eslint-plugin": "^3.1.0", + "@stylistic/eslint-plugin": "^4.0.0", "eslint-plugin-editorconfig": "^4.0.3", "eslint-plugin-import-x": "^4.6.1", "eslint-plugin-sonarjs": "^1.0.4", "eslint-plugin-tsdoc": "^0.4.0", + "globals": "^15.15.0", "typescript-eslint": "^8.25.0" }, "peerDependencies": { @@ -93,6 +93,7 @@ "eslint-plugin": { "name": "@exadel/eslint-plugin-esl", "version": "5.0.1", + "extraneous": true, "license": "MIT", "dependencies": { "kleur": "^4.1.5", @@ -1052,7 +1053,6 @@ }, "node_modules/@csstools/css-parser-algorithms": { "version": "3.0.4", - "dev": true, "funding": [ { "type": "github", @@ -1073,7 +1073,6 @@ }, "node_modules/@csstools/css-tokenizer": { "version": "3.0.3", - "dev": true, "funding": [ { "type": "github", @@ -1091,7 +1090,6 @@ }, "node_modules/@csstools/media-query-list-parser": { "version": "4.0.2", - "dev": true, "funding": [ { "type": "github", @@ -1113,7 +1111,6 @@ }, "node_modules/@csstools/selector-specificity": { "version": "5.0.0", - "dev": true, "funding": [ { "type": "github", @@ -1228,7 +1225,6 @@ }, "node_modules/@dual-bundle/import-meta-resolve": { "version": "4.1.0", - "dev": true, "license": "MIT", "funding": { "type": "github", @@ -1367,11 +1363,15 @@ "link": true }, "node_modules/@exadel/eslint-config-esl": { - "resolved": "eslint-config", + "resolved": "packages/eslint-config", "link": true }, "node_modules/@exadel/eslint-plugin-esl": { - "resolved": "eslint-plugin", + "resolved": "packages/eslint-plugin", + "link": true + }, + "node_modules/@exadel/stylelint-config-esl": { + "resolved": "packages/stylelint-config", "link": true }, "node_modules/@exadel/ui-playground": { @@ -2245,7 +2245,6 @@ }, "node_modules/@keyv/serialize": { "version": "1.0.3", - "dev": true, "license": "MIT", "dependencies": { "buffer": "^6.0.3" @@ -3077,31 +3076,73 @@ "@sinonjs/commons": "^3.0.0" } }, - "node_modules/@stylistic/eslint-plugin": { - "version": "3.1.0", - "license": "MIT", + "node_modules/@stylistic/stylelint-config": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-config/-/stylelint-config-2.0.0.tgz", + "integrity": "sha512-8J4YAxggy2Nzkb8KJIOLbtMXTPZ5gpKVmyhiiuKEUgCl9XFND5lM0e/ZZBMGEYZ68h5qcsS/jgg1wh235erRAw==", "dependencies": { - "@typescript-eslint/utils": "^8.13.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "estraverse": "^5.3.0", - "picomatch": "^4.0.2" + "@stylistic/stylelint-plugin": "^3.0.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^18.12 || >=20.9" }, "peerDependencies": { - "eslint": ">=8.40.0" + "stylelint": "^16.8.0" } }, - "node_modules/@stylistic/eslint-plugin/node_modules/picomatch": { - "version": "4.0.2", - "license": "MIT", + "node_modules/@stylistic/stylelint-plugin": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.2.tgz", + "integrity": "sha512-tylFJGMQo62alGazK74MNxFjMagYOHmBZiePZFOJK2n13JZta0uVkB3Bh5qodUmOLtRH+uxH297EibK14UKm8g==", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1", + "@csstools/media-query-list-parser": "^3.0.1", + "is-plain-object": "^5.0.0", + "postcss-selector-parser": "^6.1.2", + "postcss-value-parser": "^4.2.0", + "style-search": "^0.1.0", + "stylelint": "^16.8.2" + }, "engines": { - "node": ">=12" + "node": "^18.12 || >=20.9" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "peerDependencies": { + "stylelint": "^16.8.0" + } + }, + "node_modules/@stylistic/stylelint-plugin/node_modules/@csstools/media-query-list-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-3.0.1.tgz", + "integrity": "sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1" + } + }, + "node_modules/@stylistic/stylelint-plugin/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" } }, "node_modules/@tootallnate/once": { @@ -4114,7 +4155,6 @@ }, "node_modules/astral-regex": { "version": "2.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4382,7 +4422,6 @@ }, "node_modules/base64-js": { "version": "1.5.1", - "dev": true, "funding": [ { "type": "github", @@ -4528,7 +4567,6 @@ }, "node_modules/buffer": { "version": "6.0.3", - "dev": true, "funding": [ { "type": "github", @@ -4562,7 +4600,6 @@ }, "node_modules/cacheable": { "version": "1.8.8", - "dev": true, "license": "MIT", "dependencies": { "hookified": "^1.7.0", @@ -4571,7 +4608,6 @@ }, "node_modules/cacheable/node_modules/keyv": { "version": "5.2.3", - "dev": true, "license": "MIT", "dependencies": { "@keyv/serialize": "^1.0.2" @@ -5413,7 +5449,6 @@ }, "node_modules/colord": { "version": "2.9.3", - "dev": true, "license": "MIT" }, "node_modules/colorette": { @@ -5930,7 +5965,6 @@ }, "node_modules/css-functions-list": { "version": "3.2.3", - "dev": true, "license": "MIT", "engines": { "node": ">=12 || >=16" @@ -5938,7 +5972,6 @@ }, "node_modules/css-tree": { "version": "3.1.0", - "dev": true, "license": "MIT", "dependencies": { "mdn-data": "2.12.2", @@ -5950,7 +5983,6 @@ }, "node_modules/cssesc": { "version": "3.0.0", - "dev": true, "license": "MIT", "bin": { "cssesc": "bin/cssesc" @@ -6244,7 +6276,6 @@ }, "node_modules/dir-glob": { "version": "3.0.1", - "dev": true, "license": "MIT", "dependencies": { "path-type": "^4.0.0" @@ -7668,11 +7699,6 @@ "version": "3.1.3", "license": "MIT" }, - "node_modules/fast-diff": { - "version": "1.3.0", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/fast-fifo": { "version": "1.3.2", "license": "MIT" @@ -8476,7 +8502,6 @@ }, "node_modules/global-modules": { "version": "2.0.0", - "dev": true, "license": "MIT", "dependencies": { "global-prefix": "^3.0.0" @@ -8487,7 +8512,6 @@ }, "node_modules/global-prefix": { "version": "3.0.0", - "dev": true, "license": "MIT", "dependencies": { "ini": "^1.3.5", @@ -8500,12 +8524,10 @@ }, "node_modules/global-prefix/node_modules/ini": { "version": "1.3.8", - "dev": true, "license": "ISC" }, "node_modules/global-prefix/node_modules/which": { "version": "1.3.1", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -8589,7 +8611,6 @@ }, "node_modules/globjoin": { "version": "0.1.4", - "dev": true, "license": "MIT" }, "node_modules/gopd": { @@ -8805,7 +8826,6 @@ }, "node_modules/hookified": { "version": "1.7.1", - "dev": true, "license": "MIT" }, "node_modules/hosted-git-info": { @@ -8877,7 +8897,6 @@ }, "node_modules/html-tags": { "version": "3.3.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -8991,7 +9010,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "dev": true, "funding": [ { "type": "github", @@ -9493,7 +9511,6 @@ }, "node_modules/is-plain-object": { "version": "5.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -11380,7 +11397,6 @@ }, "node_modules/known-css-properties": { "version": "0.35.0", - "dev": true, "license": "MIT" }, "node_modules/lcid": { @@ -12055,7 +12071,6 @@ }, "node_modules/lodash.truncate": { "version": "4.4.2", - "dev": true, "license": "MIT" }, "node_modules/lodash.uniq": { @@ -12282,7 +12297,6 @@ }, "node_modules/mathml-tag-names": { "version": "2.1.3", - "dev": true, "license": "MIT", "funding": { "type": "github", @@ -12314,7 +12328,6 @@ }, "node_modules/mdn-data": { "version": "2.12.2", - "dev": true, "license": "CC0-1.0" }, "node_modules/mdurl": { @@ -12323,7 +12336,6 @@ }, "node_modules/meow": { "version": "13.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -12474,7 +12486,6 @@ }, "node_modules/nanoid": { "version": "3.3.8", - "dev": true, "funding": [ { "type": "github", @@ -16155,7 +16166,6 @@ }, "node_modules/postcss": { "version": "8.5.3", - "dev": true, "funding": [ { "type": "opencollective", @@ -16193,12 +16203,10 @@ }, "node_modules/postcss-resolve-nested-selector": { "version": "0.1.6", - "dev": true, "license": "MIT" }, "node_modules/postcss-safe-parser": { "version": "7.0.1", - "dev": true, "funding": [ { "type": "opencollective", @@ -16223,7 +16231,6 @@ }, "node_modules/postcss-selector-parser": { "version": "7.1.0", - "dev": true, "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -16235,7 +16242,6 @@ }, "node_modules/postcss-value-parser": { "version": "4.2.0", - "dev": true, "license": "MIT" }, "node_modules/posthtml": { @@ -16286,31 +16292,6 @@ "node": ">= 0.8.0" } }, - "node_modules/prettier": { - "version": "3.5.2", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/pretty-format": { "version": "29.7.0", "license": "MIT", @@ -17882,7 +17863,6 @@ }, "node_modules/source-map-js": { "version": "1.2.1", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -18269,9 +18249,15 @@ "node": ">=0.10.0" } }, + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==" + }, "node_modules/stylelint": { - "version": "16.14.1", - "dev": true, + "version": "16.15.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.15.0.tgz", + "integrity": "sha512-OK6Rs7EPdcdmjqiDycadZY4fw3f5/TC1X6/tGjnF3OosbwCeNs7nG+79MCAtjEg7ckwqTJTsku08e0Rmaz5nUw==", "funding": [ { "type": "opencollective", @@ -18282,7 +18268,6 @@ "url": "https://github.com/sponsors/stylelint" } ], - "license": "MIT", "dependencies": { "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", @@ -18297,7 +18282,7 @@ "debug": "^4.3.7", "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^10.0.5", + "file-entry-cache": "^10.0.6", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", @@ -18311,14 +18296,14 @@ "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.1.1", - "postcss": "^8.5.1", + "postcss": "^8.5.3", "postcss-resolve-nested-selector": "^0.1.6", "postcss-safe-parser": "^7.0.1", - "postcss-selector-parser": "^7.0.0", + "postcss-selector-parser": "^7.1.0", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", "string-width": "^4.2.3", - "supports-hyperlinks": "^3.1.0", + "supports-hyperlinks": "^3.2.0", "svg-tags": "^1.0.0", "table": "^6.9.0", "write-file-atomic": "^5.0.1" @@ -18330,24 +18315,8 @@ "node": ">=18.12.0" } }, - "node_modules/stylelint-prettier": { - "version": "5.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "prettier": ">=3.0.0", - "stylelint": ">=16.0.0" - } - }, "node_modules/stylelint/node_modules/ansi-regex": { "version": "5.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -18355,7 +18324,6 @@ }, "node_modules/stylelint/node_modules/array-union": { "version": "2.1.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -18363,12 +18331,10 @@ }, "node_modules/stylelint/node_modules/balanced-match": { "version": "2.0.0", - "dev": true, "license": "MIT" }, "node_modules/stylelint/node_modules/file-entry-cache": { "version": "10.0.6", - "dev": true, "license": "MIT", "dependencies": { "flat-cache": "^6.1.6" @@ -18376,7 +18342,6 @@ }, "node_modules/stylelint/node_modules/flat-cache": { "version": "6.1.6", - "dev": true, "license": "MIT", "dependencies": { "cacheable": "^1.8.8", @@ -18386,7 +18351,6 @@ }, "node_modules/stylelint/node_modules/globby": { "version": "11.1.0", - "dev": true, "license": "MIT", "dependencies": { "array-union": "^2.1.0", @@ -18405,7 +18369,6 @@ }, "node_modules/stylelint/node_modules/globby/node_modules/ignore": { "version": "5.3.2", - "dev": true, "license": "MIT", "engines": { "node": ">= 4" @@ -18413,7 +18376,6 @@ }, "node_modules/stylelint/node_modules/ignore": { "version": "7.0.3", - "dev": true, "license": "MIT", "engines": { "node": ">= 4" @@ -18421,7 +18383,6 @@ }, "node_modules/stylelint/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -18429,7 +18390,6 @@ }, "node_modules/stylelint/node_modules/signal-exit": { "version": "4.1.0", - "dev": true, "license": "ISC", "engines": { "node": ">=14" @@ -18440,7 +18400,6 @@ }, "node_modules/stylelint/node_modules/slash": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -18448,7 +18407,6 @@ }, "node_modules/stylelint/node_modules/string-width": { "version": "4.2.3", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -18461,7 +18419,6 @@ }, "node_modules/stylelint/node_modules/strip-ansi": { "version": "6.0.1", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -18472,7 +18429,6 @@ }, "node_modules/stylelint/node_modules/write-file-atomic": { "version": "5.0.1", - "dev": true, "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", @@ -18512,7 +18468,6 @@ }, "node_modules/supports-hyperlinks": { "version": "3.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0", @@ -18527,7 +18482,6 @@ }, "node_modules/supports-hyperlinks/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -18547,8 +18501,7 @@ } }, "node_modules/svg-tags": { - "version": "1.0.0", - "dev": true + "version": "1.0.0" }, "node_modules/symbol-tree": { "version": "3.2.4", @@ -18557,7 +18510,6 @@ }, "node_modules/table": { "version": "6.9.0", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "ajv": "^8.0.1", @@ -18572,7 +18524,6 @@ }, "node_modules/table/node_modules/ansi-regex": { "version": "5.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -18580,7 +18531,6 @@ }, "node_modules/table/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -18594,7 +18544,6 @@ }, "node_modules/table/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -18602,7 +18551,6 @@ }, "node_modules/table/node_modules/slice-ansi": { "version": "4.0.0", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -18618,7 +18566,6 @@ }, "node_modules/table/node_modules/string-width": { "version": "4.2.3", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -18631,7 +18578,6 @@ }, "node_modules/table/node_modules/strip-ansi": { "version": "6.0.1", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -19368,7 +19314,6 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "dev": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { @@ -20083,6 +20028,92 @@ "url": "https://github.com/sponsors/colinhacks" } }, + "packages/eslint-config": { + "name": "@exadel/eslint-config-esl", + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "@eslint/js": "^9.21.0", + "@stylistic/eslint-plugin": "^4.2.0", + "eslint-plugin-editorconfig": "^4.0.3", + "eslint-plugin-import-x": "^4.6.1", + "eslint-plugin-sonarjs": "^1.0.4", + "eslint-plugin-tsdoc": "^0.4.0", + "globals": "^16.0.0", + "typescript-eslint": "^8.25.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0" + } + }, + "packages/eslint-config/node_modules/@stylistic/eslint-plugin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-4.2.0.tgz", + "integrity": "sha512-8hXezgz7jexGHdo5WN6JBEIPHCSFyyU4vgbxevu4YLVS5vl+sxqAAGyXSzfNDyR6xMNSH5H1x67nsXcYMOHtZA==", + "dependencies": { + "@typescript-eslint/utils": "^8.23.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0" + } + }, + "packages/eslint-config/node_modules/globals": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz", + "integrity": "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/eslint-config/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "packages/eslint-plugin": { + "name": "@exadel/eslint-plugin-esl", + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "kleur": "^4.1.5", + "semver": "^7.7.1" + }, + "devDependencies": { + "@types/eslint": "^9.6.1", + "@types/semver": "^7.5.8" + }, + "peerDependencies": { + "eslint": ">=8.0.0 || >=9.0.0" + } + }, + "packages/stylelint-config": { + "name": "@exadel/stylelint-config-esl", + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "@stylistic/stylelint-config": "^2.0.0", + "@stylistic/stylelint-plugin": "^3.1.2" + }, + "peerDependencies": { + "stylelint": ">=15.0.0" + } + }, "site": { "name": "@exadel/esl-website", "version": "5.0.1", @@ -20121,6 +20152,19 @@ "engines": { "node": ">=16.x" } + }, + "stylelint-config": { + "name": "@exadel/stylelint-config-esl", + "version": "5.0.1", + "extraneous": true, + "license": "MIT", + "dependencies": { + "@stylistic/stylelint-config": "^2.0.0", + "@stylistic/stylelint-plugin": "^3.1.2" + }, + "peerDependencies": { + "stylelint": ">=16.0.0" + } } } } diff --git a/package.json b/package.json index 89d98e6815..717396c987 100644 --- a/package.json +++ b/package.json @@ -57,10 +57,9 @@ "src/polyfills/**/*.ts" ], "workspaces": [ + "packages/*", "e2e", - "site", - "eslint-config", - "eslint-plugin" + "site" ], "scripts": { "start": "cd site && npm run start", @@ -86,8 +85,8 @@ "prepare": "husky && npm run build", "preversion": "npm test", "version": "cross-env-shell \"npm version $npm_package_version --no-git-tag-version --ws\" && git add **/package*.json", - "postpack": "npm pack --workspace eslint-plugin --workspace eslint-config", - "postpublish": "npm publish --workspace eslint-plugin --workspace eslint-config", + "postpack": "npm pack --workspace packages/eslint-plugin --workspace packages/eslint-config --workspace packages/stylelint-config", + "postpublish": "npm publish --workspace packages/eslint-plugin --workspace packages/eslint-config --workspace packages/stylelint-config", "fix:less": "stylelint --fix \"**/*.less\"" }, "dependencies": { @@ -99,6 +98,7 @@ "@commitlint/config-conventional": "^19.7.1", "@exadel/eslint-config-esl": "file:eslint-config", "@exadel/eslint-plugin-esl": "file:eslint-plugin", + "@exadel/stylelint-config-esl": "file:stylelint-config", "@semantic-release/changelog": "^6.0.3", "@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/git": "^10.0.1", @@ -118,14 +118,12 @@ "kleur": "^4.1.5", "less": "^4.2.2", "lint-staged": "^15.4.3", - "postcss": "^8.5.2", + "postcss": "^8.5.3", "postcss-less": "^6.0.0", - "prettier": "^3.5.0", "rimraf": "^6.0.1", "semantic-release": "^24.2.3", "smoothscroll-polyfill": "^0.4.4", - "stylelint": "^16.14.1", - "stylelint-prettier": "^5.0.3", + "stylelint": "^16.15.0", "ts-jest": "^29.2.6", "typescript": "5.7.3" }, diff --git a/eslint-config/README.md b/packages/eslint-config/README.md similarity index 91% rename from eslint-config/README.md rename to packages/eslint-config/README.md index 199231af79..bf53437ac2 100644 --- a/eslint-config/README.md +++ b/packages/eslint-config/README.md @@ -1,4 +1,4 @@ -# [ESL](../../../) Shared ESLint Configuration +# [ESL](../../) Shared ESLint Configuration Authors: *Anastasiya Lesun, Alexey Stsefanovich (ala'n)*. @@ -25,11 +25,11 @@ Once installed, the configuration needs to be added in eslint configuration file ```js module.exports = [ - // ESLint configuration ... + // ESLint configuration ... - // Apply ESL Shared ESLint Configuration - ...require('@exadel/eslint-config-esl').typescript, - ...require('@exadel/eslint-config-esl').recommended, + // Apply ESL Shared ESLint Configuration + ...require('packages/eslint-config/index').typescript, + ...require('packages/eslint-config/index').recommended, ]; ``` diff --git a/packages/eslint-config/index.js b/packages/eslint-config/index.js new file mode 100644 index 0000000000..74a4ff01a1 --- /dev/null +++ b/packages/eslint-config/index.js @@ -0,0 +1,27 @@ +import eslintjs from '@eslint/js'; +import {configs as typescriptConfigs} from 'typescript-eslint'; + +import esbase from './rules/es.base.js'; +import tsbase from './rules/ts.base.js'; +import stylistic from './rules/stylistic.js'; + +import tsdoc from './rules/tsdoc.js'; +import sonarjs from './rules/sonarjs.js'; +import editorconfig from './rules/editorconfig.js'; +import importconfig from './rules/import.js'; + +import lang from './rules/lang.ts.js'; + +export {lang}; + +export const strict = [ + eslintjs.configs.recommended, + ...typescriptConfigs.recommended, + ...esbase, + ...tsbase, + ...stylistic, + ...sonarjs, + ...editorconfig, + ...importconfig, + ...tsdoc +]; diff --git a/eslint-config/package.json b/packages/eslint-config/package.json similarity index 92% rename from eslint-config/package.json rename to packages/eslint-config/package.json index cbbcf25605..4dcd3917ee 100644 --- a/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -1,5 +1,6 @@ { "name": "@exadel/eslint-config-esl", + "type": "module", "private": false, "version": "5.0.1", "keywords": [ @@ -14,16 +15,13 @@ "license": "MIT", "description": "Shared ESLint config used by ESL (@exadel/esl) team. Internal projects usage.", "main": "index.js", - "files": [ - "index.js", - "rules/*.js" - ], "scripts": { "test": "" }, "dependencies": { "@eslint/js": "^9.21.0", - "@stylistic/eslint-plugin": "^3.1.0", + "@stylistic/eslint-plugin": "^4.2.0", + "globals": "^16.0.0", "eslint-plugin-editorconfig": "^4.0.3", "eslint-plugin-import-x": "^4.6.1", "eslint-plugin-sonarjs": "^1.0.4", diff --git a/packages/eslint-config/rules/editorconfig.js b/packages/eslint-config/rules/editorconfig.js new file mode 100644 index 0000000000..b26a8f96ff --- /dev/null +++ b/packages/eslint-config/rules/editorconfig.js @@ -0,0 +1,17 @@ +import editorConfigPlugin from 'eslint-plugin-editorconfig'; + +export default [ + { + plugins: { + editorconfig: editorConfigPlugin + }, + rules: { + // Enforce charset check + 'editorconfig/charset': 'warn', + // Enforce EOL for all files + 'editorconfig/eol-last': 'warn', + // Require no trailing spaces + 'editorconfig/no-trailing-spaces': 'warn' + } + } +]; diff --git a/packages/eslint-config/rules/es.base.js b/packages/eslint-config/rules/es.base.js new file mode 100644 index 0000000000..ec309d307e --- /dev/null +++ b/packages/eslint-config/rules/es.base.js @@ -0,0 +1,63 @@ +export default [ + { + rules: { + // Require Guarding for-in to exclude prototype keys + 'guard-for-in': 'warn', + + // There is no blacklisted identifiers + 'id-blacklist': 'off', + + // Bitwise operators are not recommended + 'no-bitwise': 'warn', + + // Console API is formally allowed + 'no-console': 'off', + + // Labels are not allowed + 'no-labels': 'error', + + // Require implicit radix parameter for parseInt + 'radix': 'error', + + // Limit Cyclomatic Complexity + 'complexity': 'warn', + + // Require following curly brace conventions + 'curly': ['warn', 'multi-line'], + + // Max 3 classes per file (ideally 1 per file) + 'max-classes-per-file': ['warn', 3], + + // Underscores allowed due to 'private-member' notation + 'no-underscore-dangle': 'off', + + // 'var' declaration operator is not allowed + 'no-var': 'error', + + // Warn to prefer shorthand object keys + 'object-shorthand': 'warn', + + // Disallow multiple declaration per one line or declaration operator + 'one-var': ['error', 'never'], + + // Using of arrow functions is optional + 'prefer-arrow-callback': 'off', + + // Prefer const declaration operator + 'prefer-const': 'error', + + // Limit max lines count per file to 500 + 'max-lines': ['warn', 500], + + // No spread preferences in bounds of the library + 'prefer-spread': 'off' + } + }, + { + files: ['**/*.test.ts', '**/*.spec.ts'], + rules: { + // no class count limit for tests + 'max-classes-per-file': 'off' + } + } +]; diff --git a/eslint-config/rules/eslint.config.import.js b/packages/eslint-config/rules/import.js similarity index 84% rename from eslint-config/rules/eslint.config.import.js rename to packages/eslint-config/rules/import.js index cb37332e22..71a0135817 100644 --- a/eslint-config/rules/eslint.config.import.js +++ b/packages/eslint-config/rules/import.js @@ -1,7 +1,9 @@ -module.exports = [ +import importPlugin from 'eslint-plugin-import-x'; + +export default [ { plugins: { - 'import': require('eslint-plugin-import-x') + 'import': importPlugin }, rules: { // Enforce a convention in module import order @@ -21,9 +23,6 @@ module.exports = [ // Verifies that all named imports are part of the set of named exports in the referenced module. 'import/named': 'error', - // Prohibit default exports - 'import/no-default-export': 'warn', - // Forbid a module from importing itself 'import/no-self-import': 'error', @@ -31,4 +30,4 @@ module.exports = [ 'import/no-cycle': 'error' } } -] +]; diff --git a/packages/eslint-config/rules/lang.ts.js b/packages/eslint-config/rules/lang.ts.js new file mode 100644 index 0000000000..6892553106 --- /dev/null +++ b/packages/eslint-config/rules/lang.ts.js @@ -0,0 +1,17 @@ +import globals from 'globals'; +import {parser} from 'typescript-eslint'; + +export default [{ + files: ['**/*.ts', '**/*.tsx'], + languageOptions: { + parser, + ecmaVersion: 2017, + sourceType: 'module', + parserOptions: { + projectService: true + }, + globals: { + ...globals.browser + } + } +}]; diff --git a/eslint-config/rules/eslint.config.sonarjs.js b/packages/eslint-config/rules/sonarjs.js similarity index 96% rename from eslint-config/rules/eslint.config.sonarjs.js rename to packages/eslint-config/rules/sonarjs.js index e171797422..cad0bd9314 100644 --- a/eslint-config/rules/eslint.config.sonarjs.js +++ b/packages/eslint-config/rules/sonarjs.js @@ -1,8 +1,8 @@ -module.exports = [ +import sonarjs from 'eslint-plugin-sonarjs'; + +export default [ { - plugins: { - sonarjs: require('eslint-plugin-sonarjs') - }, + plugins: {sonarjs}, rules: { /** Cognitive Complexity is a measure of how hard the control flow of a function is to understand. * Functions with high Cognitive Complexity will be difficult to maintain. @@ -64,4 +64,4 @@ module.exports = [ 'sonarjs/prefer-immediate-return': 'warn' } } -] +]; diff --git a/eslint-config/rules/eslint.config.stylistic.js b/packages/eslint-config/rules/stylistic.js similarity index 95% rename from eslint-config/rules/eslint.config.stylistic.js rename to packages/eslint-config/rules/stylistic.js index 07c05e7256..a229a3629c 100644 --- a/eslint-config/rules/eslint.config.stylistic.js +++ b/packages/eslint-config/rules/stylistic.js @@ -1,7 +1,9 @@ -module.exports = [ +import stylistic from '@stylistic/eslint-plugin'; + +export default [ { plugins: { - '@stylistic': require('@stylistic/eslint-plugin') + '@stylistic': stylistic }, rules: { '@stylistic/arrow-parens': ['warn', 'always'], @@ -124,10 +126,10 @@ module.exports = [ } }, { - files: ["**/*.test.ts", "**/*.spec.ts"], + files: ['**/*.test.ts', '**/*.spec.ts'], rules: { // It's ok to write braces single line in tests - '@stylistic/brace-style': "off", + '@stylistic/brace-style': 'off', } }, -] +]; diff --git a/eslint-config/rules/eslint.config.coderules.js b/packages/eslint-config/rules/ts.base.js similarity index 71% rename from eslint-config/rules/eslint.config.coderules.js rename to packages/eslint-config/rules/ts.base.js index 985ce4a8e7..8075f57a20 100644 --- a/eslint-config/rules/eslint.config.coderules.js +++ b/packages/eslint-config/rules/ts.base.js @@ -1,57 +1,12 @@ -module.exports = [ +import {plugin} from 'typescript-eslint'; + +export default [ { + files: ['**/*.ts', '**/*.tsx'], + plugins: { + '@typescript-eslint': plugin + }, rules: { - // Verify calls of super() in constructors - 'constructor-super': 'warn', - - // Requires === and !== usage - 'eqeqeq': 'warn', - - // Require Guarding for-in to exclude prototype keys - 'guard-for-in': 'warn', - - // There is no blacklisted identifiers - 'id-blacklist': 'off', - - // Bitwise operators are not recommended - 'no-bitwise': 'warn', - - // Disallow use of caller/callee - 'no-caller': 'error', - - // Warn about assignment operators in conditional statements - 'no-cond-assign': 'warn', - - // Console API is formally allowed - 'no-console': 'off', - - // Debugger operator is not allowed - 'no-debugger': 'error', - - // Allows case statement to fallthrough - 'no-fallthrough': 'off', - - // Warn about using redundant primitive wrapper instances usage - 'no-new-wrappers': 'warn', - - // Warn about redundant initializing to undefined - 'no-undef-init': 'warn', - - // Disallow control flow statements in finally blocks - 'no-unsafe-finally': 'error', - - // Labels are not allowed - 'no-labels': 'error', - - // Require implicit radix parameter for parseInt - 'radix': 'error', - - // Require calls to isNaN() when checking for NaN - 'use-isnan': 'error', - - // Enforce comparing typeof expressions against valid strings - 'valid-typeof': 'error', - // Enforces consistent usage of type imports '@typescript-eslint/consistent-type-imports': [ 'error', { @@ -62,39 +17,20 @@ module.exports = [ // Disallow the use of custom TypeScript modules and namespaces '@typescript-eslint/no-namespace': 'error', - // Disallows using a non-null assertion after an optional chain expression - '@typescript-eslint/no-non-null-asserted-optional-chain': 'error', - - // Disallows invocation of require() - '@typescript-eslint/no-require-imports': 'error', - - // Disallow aliasing this - '@typescript-eslint/no-this-alias': 'error', - // Flags unnecessary equality comparisons against boolean literals '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error', // Disallows the use of require statements except in import statements '@typescript-eslint/no-var-requires': 'error', - // Prefer usage of as const over literal type - '@typescript-eslint/prefer-as-const': 'error', - - // Disallow iterating over an array with a for-in loop - '@typescript-eslint/no-for-in-array': 'error', - - // Disallow extra non-null assertion - '@typescript-eslint/no-extra-non-null-assertion': 'error', - // Enforce default parameters to be last - 'default-param-last': 'off', '@typescript-eslint/default-param-last': 'error', // Prefers member overloads to be consecutive '@typescript-eslint/adjacent-overload-signatures': 'warn', // Prefers using either T[] or Array for arrays - '@typescript-eslint/array-type': 'warn', + '@typescript-eslint/array-type': 'warn', // Warn about awaiting of a value that is not a Thenable '@typescript-eslint/await-thenable': 'warn', @@ -121,9 +57,6 @@ module.exports = [ // Prefers function types instead of interfaces with call signatures '@typescript-eslint/prefer-function-type': 'warn', - // Sets preference level for triple slash directives versus ES6-style import declarations - '@typescript-eslint/triple-slash-reference': 'warn', - // Warns if a type assertion does not change the type of an expression '@typescript-eslint/no-unnecessary-type-assertion': 'warn', @@ -160,7 +93,6 @@ module.exports = [ '@typescript-eslint/no-empty-interface': 'off', // Allows empty functions - 'no-empty-function': 'off', '@typescript-eslint/no-empty-function': 'off', // Allows usage of the any type @@ -182,17 +114,13 @@ module.exports = [ '@typescript-eslint/explicit-member-accessibility': 'off', /** Do not require a consistent member declaration order - * TODO: discuss for the future + * TODO: discuss for the future */ - 'member-ordering': 'off', '@typescript-eslint/member-ordering': 'off', // There is no preferences of a particular method signature syntax '@typescript-eslint/method-signature-style': 'off', - // Ensure .toString() is only called on objects which provide useful information when stringified - '@typescript-eslint/no-base-to-string': 'warn', - // Warn about non-null assertion in locations that may be confusing '@typescript-eslint/no-confusing-non-null-assertion': 'warn', @@ -203,7 +131,7 @@ module.exports = [ '@typescript-eslint/no-extraneous-class': 'off', /** Do not require Promise-like values to be handled appropriately - * TODO: enable + * TODO: enable */ '@typescript-eslint/no-floating-promises': 'off', @@ -259,31 +187,91 @@ module.exports = [ '@typescript-eslint/no-unnecessary-condition': 'off', // Allows generic Array constructors - 'no-array-constructor': 'off', '@typescript-eslint/no-array-constructor': 'off', // Allows the use of variables before they are defined - 'no-use-before-define': 'off', - '@typescript-eslint/no-use-before-define': 'off' + '@typescript-eslint/no-use-before-define': 'off', + + // Do not enforce dot notation whenever possible + '@typescript-eslint/dot-notation': 'off', + + // Prefers consistent usage of type assertions + '@typescript-eslint/consistent-type-assertions': 'warn', + + // Require the use of the namespace keyword instead of the module keyword to declare custom TypeScript modules + '@typescript-eslint/prefer-namespace-keyword': 'warn', + + // Allows initialization in variable declarations + '@typescript-eslint/init-declarations': 'off', + + // Warn about duplicate class members + '@typescript-eslint/no-dupe-class-members': 'warn', + + // The use of eval()-like methods is not recommended + '@typescript-eslint/no-implied-eval': 'warn', + + // Allows this keywords outside of classes or class-like objects + '@typescript-eslint/no-invalid-this': 'off', + + // Warn about function declarations that contain unsafe references inside loop statements + '@typescript-eslint/no-loop-func': 'warn', + + // Warn about literal numbers that lose precision + '@typescript-eslint/no-loss-of-precision': 'warn', + + // Disallow variable redeclaration + '@typescript-eslint/no-redeclare': 'error', + + // Warn about variable declarations that are shadowing variables declared in the outer scope + '@typescript-eslint/no-shadow': 'warn', + + // Warn about throwing literals as exceptions + '@typescript-eslint/only-throw-error': 'warn', + + // Allows unused expressions + '@typescript-eslint/no-unused-expressions': 'off', + + // Warn about unused variables + '@typescript-eslint/no-unused-vars': [ + 'warn', + { + vars: 'all', caughtErrors: 'none', args: 'none' + } + ], + + // Warn about unnecessary constructors + '@typescript-eslint/no-useless-constructor': 'warn', + + // Do not warn if an async function has no await expression + '@typescript-eslint/require-await': 'off', + + // Prefers consistent returning of awaited values + '@typescript-eslint/return-await': 'warn' } }, { - files: ["**/*.shape.ts"], + files: ['**/*.shape.ts'], + plugins: { + '@typescript-eslint': plugin + }, rules: { - '@typescript-eslint/no-namespace': "off", + '@typescript-eslint/no-namespace': 'off', // Temporary of as false positive - '@typescript-eslint/no-unnecessary-type-arguments': "off" + '@typescript-eslint/no-unnecessary-type-arguments': 'off' } }, { - files: ["**/*.test.ts", "**/*.spec.ts"], + files: ['**/*.test.ts', '**/*.spec.ts'], + plugins: { + '@typescript-eslint': plugin + }, rules: { // ts-ignore is off to test clean es cases - '@typescript-eslint/ban-ts-comment': "off", + '@typescript-eslint/ban-ts-comment': 'off', // there is no need to evaluate tests strictly - '@typescript-eslint/non-nullable-type-assertion-style': "off", + '@typescript-eslint/non-nullable-type-assertion-style': 'off', // return type on functions or class methods is not required in tests - '@typescript-eslint/explicit-function-return-type': "off" + '@typescript-eslint/explicit-function-return-type': 'off' } } -] +]; diff --git a/packages/eslint-config/rules/tsdoc.js b/packages/eslint-config/rules/tsdoc.js new file mode 100644 index 0000000000..8e19c92582 --- /dev/null +++ b/packages/eslint-config/rules/tsdoc.js @@ -0,0 +1,12 @@ +import tsdoc from 'eslint-plugin-tsdoc'; + +export default [ + { + files: ['**/*.ts', '**/*.tsx'], + plugins: {tsdoc}, + rules: { + // Enable TS Doc syntax check + 'tsdoc/syntax': 'warn' + } + } +]; diff --git a/packages/eslint-plugin/.gitignore b/packages/eslint-plugin/.gitignore new file mode 100644 index 0000000000..1521c8b765 --- /dev/null +++ b/packages/eslint-plugin/.gitignore @@ -0,0 +1 @@ +dist diff --git a/eslint-plugin/README.md b/packages/eslint-plugin/README.md similarity index 95% rename from eslint-plugin/README.md rename to packages/eslint-plugin/README.md index a1fd491164..eb964ba6df 100644 --- a/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -1,4 +1,4 @@ -# [ESL](../../../) migration support +# [ESL](../../) migration support Authors: *Natalia Smirnova, Alexey Stsefanovich (ala'n)*. @@ -37,12 +37,13 @@ Or in YAML: ``` For ESLint +8.0.0 with Flat config: + ```js module.exports = [ - // ESLint configuration + // ESLint configuration - // Apply Recomended ESL ESLint Plugin checks - ...require('@exadel/eslint-plugin-esl').recommended, + // Apply Recomended ESL ESLint Plugin checks + ...require('@exadel/eslint-plugin-esl').recommended, ]; ``` diff --git a/eslint-plugin/defaults/es-config-default.eslint.yml b/packages/eslint-plugin/defaults/es-config-default.eslint.yml similarity index 100% rename from eslint-plugin/defaults/es-config-default.eslint.yml rename to packages/eslint-plugin/defaults/es-config-default.eslint.yml diff --git a/eslint-plugin/defaults/ts-config-default.eslint.yml b/packages/eslint-plugin/defaults/ts-config-default.eslint.yml similarity index 100% rename from eslint-plugin/defaults/ts-config-default.eslint.yml rename to packages/eslint-plugin/defaults/ts-config-default.eslint.yml diff --git a/eslint-plugin/jest.config.js b/packages/eslint-plugin/jest.config.js similarity index 100% rename from eslint-plugin/jest.config.js rename to packages/eslint-plugin/jest.config.js diff --git a/eslint-plugin/package.json b/packages/eslint-plugin/package.json similarity index 100% rename from eslint-plugin/package.json rename to packages/eslint-plugin/package.json diff --git a/eslint-plugin/src/core/ast.traverse.ts b/packages/eslint-plugin/src/core/ast.traverse.ts similarity index 100% rename from eslint-plugin/src/core/ast.traverse.ts rename to packages/eslint-plugin/src/core/ast.traverse.ts diff --git a/eslint-plugin/src/core/ast.utils.ts b/packages/eslint-plugin/src/core/ast.utils.ts similarity index 100% rename from eslint-plugin/src/core/ast.utils.ts rename to packages/eslint-plugin/src/core/ast.utils.ts diff --git a/eslint-plugin/src/core/check-version.ts b/packages/eslint-plugin/src/core/check-version.ts similarity index 100% rename from eslint-plugin/src/core/check-version.ts rename to packages/eslint-plugin/src/core/check-version.ts diff --git a/eslint-plugin/src/core/deprecated-alias.ts b/packages/eslint-plugin/src/core/deprecated-alias.ts similarity index 100% rename from eslint-plugin/src/core/deprecated-alias.ts rename to packages/eslint-plugin/src/core/deprecated-alias.ts diff --git a/eslint-plugin/src/core/deprecated-class-method.ts b/packages/eslint-plugin/src/core/deprecated-class-method.ts similarity index 100% rename from eslint-plugin/src/core/deprecated-class-method.ts rename to packages/eslint-plugin/src/core/deprecated-class-method.ts diff --git a/eslint-plugin/src/core/deprecated-path.ts b/packages/eslint-plugin/src/core/deprecated-path.ts similarity index 100% rename from eslint-plugin/src/core/deprecated-path.ts rename to packages/eslint-plugin/src/core/deprecated-path.ts diff --git a/eslint-plugin/src/core/log.ts b/packages/eslint-plugin/src/core/log.ts similarity index 100% rename from eslint-plugin/src/core/log.ts rename to packages/eslint-plugin/src/core/log.ts diff --git a/eslint-plugin/src/index.ts b/packages/eslint-plugin/src/index.ts similarity index 100% rename from eslint-plugin/src/index.ts rename to packages/eslint-plugin/src/index.ts diff --git a/eslint-plugin/src/rules/4/all.rules.ts b/packages/eslint-plugin/src/rules/4/all.rules.ts similarity index 100% rename from eslint-plugin/src/rules/4/all.rules.ts rename to packages/eslint-plugin/src/rules/4/all.rules.ts diff --git a/eslint-plugin/src/rules/4/deprecated.aliases.ts b/packages/eslint-plugin/src/rules/4/deprecated.aliases.ts similarity index 100% rename from eslint-plugin/src/rules/4/deprecated.aliases.ts rename to packages/eslint-plugin/src/rules/4/deprecated.aliases.ts diff --git a/eslint-plugin/src/rules/4/deprecated.class-methods.ts b/packages/eslint-plugin/src/rules/4/deprecated.class-methods.ts similarity index 100% rename from eslint-plugin/src/rules/4/deprecated.class-methods.ts rename to packages/eslint-plugin/src/rules/4/deprecated.class-methods.ts diff --git a/eslint-plugin/src/rules/4/deprecated.import.ts b/packages/eslint-plugin/src/rules/4/deprecated.import.ts similarity index 100% rename from eslint-plugin/src/rules/4/deprecated.import.ts rename to packages/eslint-plugin/src/rules/4/deprecated.import.ts diff --git a/eslint-plugin/src/rules/5/all.rules.ts b/packages/eslint-plugin/src/rules/5/all.rules.ts similarity index 100% rename from eslint-plugin/src/rules/5/all.rules.ts rename to packages/eslint-plugin/src/rules/5/all.rules.ts diff --git a/eslint-plugin/src/rules/5/deprecated.aliases.ts b/packages/eslint-plugin/src/rules/5/deprecated.aliases.ts similarity index 100% rename from eslint-plugin/src/rules/5/deprecated.aliases.ts rename to packages/eslint-plugin/src/rules/5/deprecated.aliases.ts diff --git a/eslint-plugin/test/deprecated-alias.invalid.test.ts b/packages/eslint-plugin/test/deprecated-alias.invalid.test.ts similarity index 100% rename from eslint-plugin/test/deprecated-alias.invalid.test.ts rename to packages/eslint-plugin/test/deprecated-alias.invalid.test.ts diff --git a/eslint-plugin/test/deprecated-alias.valid.test.ts b/packages/eslint-plugin/test/deprecated-alias.valid.test.ts similarity index 100% rename from eslint-plugin/test/deprecated-alias.valid.test.ts rename to packages/eslint-plugin/test/deprecated-alias.valid.test.ts diff --git a/eslint-plugin/test/deprecated-class-method.test.ts b/packages/eslint-plugin/test/deprecated-class-method.test.ts similarity index 100% rename from eslint-plugin/test/deprecated-class-method.test.ts rename to packages/eslint-plugin/test/deprecated-class-method.test.ts diff --git a/eslint-plugin/tsconfig.build.json b/packages/eslint-plugin/tsconfig.build.json similarity index 100% rename from eslint-plugin/tsconfig.build.json rename to packages/eslint-plugin/tsconfig.build.json diff --git a/eslint-plugin/tsconfig.json b/packages/eslint-plugin/tsconfig.json similarity index 100% rename from eslint-plugin/tsconfig.json rename to packages/eslint-plugin/tsconfig.json diff --git a/packages/stylelint-config/README.md b/packages/stylelint-config/README.md new file mode 100644 index 0000000000..3d09a3debc --- /dev/null +++ b/packages/stylelint-config/README.md @@ -0,0 +1,36 @@ +# [ESL](../../) Shared StyleLint Configuration + +Authors: *Alexey Stsefanovich (ala'n)*. + + + +Packages maintained by ESL Team often use StyleLint to ensure code quality and consistency. +To simplify the process of configuring StyleLint for these packages, we have developed a shared StyleLint configuration. +This configuration is designed to be used as a base for StyleLint configuration in projects that use ESL package, +or decide to follow ESL source code style. + + + +### Installation + +To use ESL shared StyleLint configuration, you need to install it as npm package: + +```bash +npm install --save-dev @exadel/stylelint-config-esl +``` + +Ensure that you have the StyleLint package of version 15.0.0 or higher, +shared configuration uses separate @stylistic package to check style rules. + +Once installed, the configuration needs to be added in StyleLint configuration file: + +```js +module.exports = { + // StyleLint configuration + // ... + extends: [ + // Apply ESL Shared StyleLint Configuration + '@exadel/stylelint-config-esl', + ] +}; +``` diff --git a/packages/stylelint-config/index.js b/packages/stylelint-config/index.js new file mode 100644 index 0000000000..f58f37e369 --- /dev/null +++ b/packages/stylelint-config/index.js @@ -0,0 +1,13 @@ +/** @type {import('stylelint').Config} */ +export default { + plugins: ['@stylistic/stylelint-plugin'], + extends: ['@stylistic/stylelint-config'], + rules: { + '@stylistic/string-quotes': 'single', + '@stylistic/declaration-colon-newline-after': null, + '@stylistic/max-line-length': null, + '@stylistic/indentation': [2, { + ignore: ['value', 'inside-parens'] + }] + } +}; diff --git a/packages/stylelint-config/package.json b/packages/stylelint-config/package.json new file mode 100644 index 0000000000..599d011d35 --- /dev/null +++ b/packages/stylelint-config/package.json @@ -0,0 +1,50 @@ +{ + "name": "@exadel/stylelint-config-esl", + "type": "module", + "private": false, + "version": "5.0.1", + "keywords": [ + "stylelint", + "stylelint-config", + "esl" + ], + "publishConfig": { + "access": "public", + "scope": "@exadel" + }, + "license": "MIT", + "description": "Shared Stylelint config used by ESL (@exadel/esl) team. Internal projects usage.", + "main": "index.js", + "scripts": { + "test": "" + }, + "dependencies": { + "@stylistic/stylelint-config": "^2.0.0", + "@stylistic/stylelint-plugin": "^3.1.2" + }, + "peerDependencies": { + "stylelint": ">=15.0.0" + }, + "maintainers": [ + { + "name": "ala-n", + "email": "astsefanovich@exadel.com" + }, + { + "name": "yadamska", + "email": "yadamska@exadel.com" + }, + { + "name": "dshovchko", + "email": "dshovchko@exadel.com" + }, + { + "name": "abarmina", + "email": "abarmina@exadel.com" + }, + { + "name": "alesun", + "email": "alesun@exadel.com" + } + ] +} diff --git a/site/src/common/code.less b/site/src/common/code.less index 699ede5435..f29d61655f 100644 --- a/site/src/common/code.less +++ b/site/src/common/code.less @@ -3,8 +3,14 @@ pre, code { - font-family: SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', - 'Courier New', monospace; + font-family: + SFMono-Regular, + Menlo, + Monaco, + Consolas, + 'Liberation Mono', + 'Courier New', + monospace; font-size: 1em; } diff --git a/site/src/common/reboot.less b/site/src/common/reboot.less index 4535e8c4d6..b418d99425 100644 --- a/site/src/common/reboot.less +++ b/site/src/common/reboot.less @@ -18,8 +18,14 @@ body { margin: 0; - font-family: system-ui, 'Segoe UI', sans-serif, 'Apple Color Emoji', - 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + font-family: + system-ui, + 'Segoe UI', + sans-serif, + 'Apple Color Emoji', + 'Segoe UI Emoji', + 'Segoe UI Symbol', + 'Noto Color Emoji'; font-size: 1rem; font-weight: 400; line-height: 1.5; diff --git a/site/src/common/tabs.less b/site/src/common/tabs.less index c7341045b5..97e2831b44 100644 --- a/site/src/common/tabs.less +++ b/site/src/common/tabs.less @@ -8,7 +8,7 @@ & > .esl-d-accordion-header { border-radius: calc(0.5rem - 1px); - transition: border-radius 0s linear.5s; + transition: border-radius 0s linear 0.5s; &[active] { color: @primary-blue; border-bottom-left-radius: 0; diff --git a/site/src/navigation/footer/footer.less b/site/src/navigation/footer/footer.less index 3b6db3e615..6940a354bb 100644 --- a/site/src/navigation/footer/footer.less +++ b/site/src/navigation/footer/footer.less @@ -3,14 +3,13 @@ .footer { @footer-primary: @primary-blue; @footer-gradient: linear-gradient( - to right, - @primary-bg, - @footer-primary, - @footer-primary, - #ffffff, - @primary-bg - ) - 47% 0%; + to right, + @primary-bg, + @footer-primary, + @footer-primary, + #ffffff, + @primary-bg + ) 47% 0%; display: block; @media print { diff --git a/src/modules/esl-popup/core/esl-popup.mixin.less b/src/modules/esl-popup/core/esl-popup.mixin.less index 365384f122..33e3ea337f 100644 --- a/src/modules/esl-popup/core/esl-popup.mixin.less +++ b/src/modules/esl-popup/core/esl-popup.mixin.less @@ -1,8 +1,10 @@ -.esl-popup-arrow-init(@arrowClassName: esl-popup-arrow, - @popupArrowSize: 20px, - @popupBackgroundColor: #FFF, - @popupBorderColor: #DBDBDB, - @popupBorderWidth: 1px) { +.esl-popup-arrow-init( + @arrowClassName: esl-popup-arrow, + @popupArrowSize: 20px, + @popupBackgroundColor: #FFF, + @popupBorderColor: #DBDBDB, + @popupBorderWidth: 1px +) { @popupArrowHalf: (@popupArrowSize / 2); @popupArrowShift: ( @popupArrowSize * 0.2071 - @popupBorderWidth @@ -55,13 +57,15 @@ } } -.esl-popup-init(@className: esl-popup, - @arrowClassName: esl-popup-arrow, - @arrowSize: 20px, - @backgroundColor: #FFF, - @borderColor: #DBDBDB, - @borderWidth: 1px, - @zIndex: 999) { +.esl-popup-init( + @className: esl-popup, + @arrowClassName: esl-popup-arrow, + @arrowSize: 20px, + @backgroundColor: #FFF, + @borderColor: #DBDBDB, + @borderWidth: 1px, + @zIndex: 999 +) { .@{className} { position: absolute; left: 0;