From fc6d725380d23475589aab7048056d0906fc7f18 Mon Sep 17 00:00:00 2001 From: Cole Bemis Date: Thu, 15 Jun 2023 14:31:01 -0700 Subject: [PATCH 01/18] wip --- src/rules/__tests__/no-css-vars.test.js | 30 ++++++++++++++++ src/rules/no-css-vars.js | 47 +++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 src/rules/__tests__/no-css-vars.test.js create mode 100644 src/rules/no-css-vars.js diff --git a/src/rules/__tests__/no-css-vars.test.js b/src/rules/__tests__/no-css-vars.test.js new file mode 100644 index 00000000..b7d1a7de --- /dev/null +++ b/src/rules/__tests__/no-css-vars.test.js @@ -0,0 +1,30 @@ +const rule = require('../no-css-vars') +const {RuleTester} = require('eslint') + +const ruleTester = new RuleTester({ + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + ecmaFeatures: { + jsx: true + } + } +}) + +// report all strings that start with 'var(--color-' +// autofix strings: 'var(--color-fg-default)' -> 'fg.default' + +ruleTester.run('no-deprecated-colors', rule, { + valid: [`{color: 'text.primary'}`], + invalid: [ + { + code: `{color: 'var(--color-text-primary)'}`, + output: `{color: "text-primary"}`, + errors: [ + { + message: 'Oops' + } + ] + } + ] +}) diff --git a/src/rules/no-css-vars.js b/src/rules/no-css-vars.js new file mode 100644 index 00000000..4003c5c1 --- /dev/null +++ b/src/rules/no-css-vars.js @@ -0,0 +1,47 @@ +const deprecatedVars = require('@primer/primitives/dist/deprecated/colors') +const removedVars = require('@primer/primitives/dist/removed/colors') +const traverse = require('eslint-traverse') +const {isImportedFrom} = require('../utils/is-imported-from') +const {isPrimerComponent} = require('../utils/is-primer-component') + +module.exports = { + meta: { + type: 'suggestion', + hasSuggestions: true, + fixable: 'code', + schema: [ + { + type: 'object', + properties: { + skipImportCheck: { + type: 'boolean' + }, + checkAllStrings: { + type: 'boolean' + } + }, + additionalProperties: false + } + ] + }, + create(context) { + return { + Literal(node) { + // console.log(node) + + if (typeof node.value === 'string' && node.value.startsWith('var(--color-')) { + const match = node.value.match(/^var\(--color-(.+)\)$/) + if (!match) return + const colorName = match[1] + context.report({ + node, + message: `Oops`, + fix(fixer) { + return fixer.replaceText(node, `"${colorName}"`) + } + }) + } + } + } + } +} From b7a836d6d0a71dd067d7da2ce962dc0c919b42f3 Mon Sep 17 00:00:00 2001 From: langermank <18661030+langermank@users.noreply.github.com> Date: Thu, 22 Jun 2023 19:25:58 -0700 Subject: [PATCH 02/18] new attempt --- package-lock.json | 4 +- src/rules/__tests__/no-color-css-vars.test.js | 43 ++++++++++++++++ src/rules/__tests__/no-css-vars.test.js | 13 +++++ src/rules/no-color-css-vars.js | 51 +++++++++++++++++++ src/temp-fix.json | 6 +++ 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 src/rules/__tests__/no-color-css-vars.test.js create mode 100644 src/rules/no-color-css-vars.js create mode 100644 src/temp-fix.json diff --git a/package-lock.json b/package-lock.json index c7419cbb..a27f065f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "eslint-plugin-primer-react", - "version": "1.0.1", + "version": "3.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "eslint-plugin-primer-react", - "version": "1.0.1", + "version": "3.0.0", "license": "MIT", "dependencies": { "@styled-system/props": "^5.1.5", diff --git a/src/rules/__tests__/no-color-css-vars.test.js b/src/rules/__tests__/no-color-css-vars.test.js new file mode 100644 index 00000000..6a652853 --- /dev/null +++ b/src/rules/__tests__/no-color-css-vars.test.js @@ -0,0 +1,43 @@ +const rule = require('../no-color-css-vars') +const {RuleTester} = require('eslint') + +const ruleTester = new RuleTester({ + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + ecmaFeatures: { + jsx: true + } + } +}) + +// report all strings that start with 'var(--color-' +// autofix strings: 'var(--color-fg-default)' -> 'fg.default' + +{ + /* `, + output: ``, + errors: [ + { + message: 'Replace var(--color-fg-muted) with fg.muted' + } + ] + }, + { + code: ``, + output: ``, + errors: [ + { + message: 'Replace var(--color-accent-fg) with accent.fg' + } + ] + }, + { + code: ``, + output: ``, + errors: [ + { + message: 'Replace var(--color-canvas-subtle) with canvas.subtle' + } + ] + }, + { + code: ``, + output: ``, + errors: [ + { + message: 'Replace var(--color-border-default) with border.default' + } + ] + }, + { + code: ``, + output: ``, + errors: [ + { + message: 'Replace var(--color-border-default) with border.default' + } + ] + }, + { + code: ``, + output: ``, + errors: [ + { + message: 'Replace var(--color-canvas-default) with canvas.default' + } + ] + }, + { + code: ``, + output: ``, + errors: [ + { + message: 'Replace var(--color-canvas-default) with canvas.default' + } + ] + }, + { + code: ``, + output: ``, + errors: [ + { + message: 'Replace var(--color-canvas-default) with canvas.default' + } + ] + }, + // { + // code: `import {sx, SxProp} from '@primer/react' export const HighlightToken = styled.span < SxProp > \`color: var(--color-accent-emphasis); ${sx}\` const ClickableTokenSpan = styled(HighlightToken)\` &:hover, &:focus { background-color: accent.muted;}\``, + // output: `import {sx, SxProp} from '@primer/react' export const HighlightToken = styled.span < SxProp > \`color: accent.emphasis; ${sx}\` const ClickableTokenSpan = styled(HighlightToken)\` &:hover, &:focus { background-color: accent.muted;}\``, + // errors: [ + // { + // message: 'Replace var(--color-accent-emphasis) with accent.emphasis' + // } + // ] + // } + { + code: ``, + output: ``, errors: [ { - message: 'Replace var(--color-fg-default) with fg.default' + message: 'Replace var(--color-border-default) with border.default' } ] } diff --git a/src/rules/no-color-css-vars.js b/src/rules/no-color-css-vars.js index 89159f4d..e13a7ca5 100644 --- a/src/rules/no-color-css-vars.js +++ b/src/rules/no-color-css-vars.js @@ -1,4 +1,4 @@ -const cssVars = require('../temp-fix.json') +const cssVars = require('../utils/css-var-map.json') module.exports = { meta: { diff --git a/src/temp-fix.json b/src/temp-fix.json deleted file mode 100644 index 65df206b..00000000 --- a/src/temp-fix.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "--color-fg-default": "fg.default", - "--color-fg-muted": "fg.muted", - "--color-fg-subtle": "fg.subtle", - "--color-fg-onEmphasis": "fg.onEmphasis" -} diff --git a/src/utils/css-var-map.json b/src/utils/css-var-map.json new file mode 100644 index 00000000..0aa1b359 --- /dev/null +++ b/src/utils/css-var-map.json @@ -0,0 +1,75 @@ +{ + "--color-canvas-default-transparent": "canvasDefaultTransparent", + "--color-control-border-color-emphasis": "control.borderColor.emphasis", + "--color-action-list-item-inline-divider": "actionListItem.inlineDivider", + "--color-action-list-item-default-hover-bg": "actionListItem.default.hoverBg", + "--color-action-list-item-default-hover-border": "actionListItem.default.hoverBorder", + "--color-action-list-item-default-active-bg": "actionListItem.default.activeBg", + "--color-action-list-item-default-active-border": "actionListItem.default.activeBorder", + "--color-action-list-item-default-selected-bg": "actionListItem.default.selectedBg", + "--color-action-list-item-danger-hover-bg": "actionListItem.danger.hoverBg", + "--color-action-list-item-danger-active-bg": "actionListItem.danger.activeBg", + "--color-action-list-item-danger-hover-text": "actionListItem.danger.hoverText", + "--color-fg-default": "fg.default", + "--color-fg-muted": "fg.muted", + "--color-fg-subtle": "fg.subtle", + "--color-fg-on-emphasis": "fg.onEmphasis", + "--color-canvas-default": "canvas.default", + "--color-canvas-overlay": "canvas.overlay", + "--color-canvas-inset": "canvas.inset", + "--color-canvas-subtle": "canvas.subtle", + "--color-border-default": "border.default", + "--color-border-muted": "border.muted", + "--color-border-subtle": "border.subtle", + "--color-shadow-small": "shadow.small", + "--color-shadow-medium": "shadow.medium", + "--color-shadow-large": "shadow.large", + "--color-shadow-extra-large": "shadow.extraLarge", + "--color-neutral-emphasis-plus": "neutral.emphasisPlus", + "--color-neutral-emphasis": "neutral.emphasis", + "--color-neutral-muted": "neutral.muted", + "--color-neutral-subtle": "neutral.subtle", + "--color-accent-fg": "accent.fg", + "--color-accent-emphasis": "accent.emphasis", + "--color-accent-muted": "accent.muted", + "--color-accent-subtle": "accent.subtle", + "--color-success-fg": "success.fg", + "--color-success-emphasis": "success.emphasis", + "--color-success-muted": "success.muted", + "--color-success-subtle": "success.subtle", + "--color-attention-fg": "attention.fg", + "--color-attention-emphasis": "attention.emphasis", + "--color-attention-muted": "attention.muted", + "--color-attention-subtle": "attention.subtle", + "--color-severe-fg": "severe.fg", + "--color-severe-emphasis": "severe.emphasis", + "--color-severe-muted": "severe.muted", + "--color-severe-subtle": "severe.subtle", + "--color-danger-fg": "danger.fg", + "--color-danger-emphasis": "danger.emphasis", + "--color-danger-muted": "danger.muted", + "--color-danger-subtle": "danger.subtle", + "--color-open-fg": "open.fg", + "--color-open-emphasis": "open.emphasis", + "--color-open-muted": "open.muted", + "--color-open-subtle": "open.subtle", + "--color-closed-fg": "closed.fg", + "--color-closed-emphasis": "closed.emphasis", + "--color-closed-muted": "closed.muted", + "--color-closed-subtle": "closed.subtle", + "--color-done-fg": "done.fg", + "--color-done-emphasis": "done.emphasis", + "--color-done-muted": "done.muted", + "--color-done-subtle": "done.subtle", + "--color-sponsors-fg": "sponsors.fg", + "--color-sponsors-emphasis": "sponsors.emphasis", + "--color-sponsors-muted": "sponsors.muted", + "--color-sponsors-subtle": "sponsors.subtle", + "--color-primer-fg-disabled": "actionListItem", + "--color-primer-canvas-backdrop": "primer.canvas.backdrop", + "--color-primer-canvas-sticky": "primer.canvas.sticky", + "--color-primer-border-active": "primer.border.active", + "--color-primer-border-contrast": "primer.border.contrast", + "--color-primer-shadow-highlight": "primer.shadow.highlight", + "--color-primer-shadow-inset": "primer.shadow.inset" +} From a38be538d32ec8c289870060cca87ecade821799 Mon Sep 17 00:00:00 2001 From: langermank <18661030+langermank@users.noreply.github.com> Date: Fri, 23 Jun 2023 09:58:02 -0700 Subject: [PATCH 04/18] cleanup --- src/rules/__tests__/no-color-css-vars.test.js | 62 +++++++++---------- src/rules/__tests__/no-css-vars.test.js | 43 ------------- src/rules/no-color-css-vars.js | 60 ++++++++++++------ src/rules/no-css-vars.js | 47 -------------- 4 files changed, 73 insertions(+), 139 deletions(-) delete mode 100644 src/rules/__tests__/no-css-vars.test.js delete mode 100644 src/rules/no-css-vars.js diff --git a/src/rules/__tests__/no-color-css-vars.test.js b/src/rules/__tests__/no-color-css-vars.test.js index 81620f4c..84f1b528 100644 --- a/src/rules/__tests__/no-color-css-vars.test.js +++ b/src/rules/__tests__/no-color-css-vars.test.js @@ -11,12 +11,21 @@ const ruleTester = new RuleTester({ } }) -// report all strings that start with 'var(--color-' -// autofix strings: 'var(--color-fg-default)' -> 'fg.default' -// color, backgroundColor, bg, - ruleTester.run('no-color-css-vars', rule, { - valid: [`{color: 'fg.default'}`], + valid: [ + { + code: `{color: 'fg.default'}` + }, + { + code: `` + }, + { + code: `` + }, + { + code: `
` + } + ], invalid: [ { code: ``, @@ -27,21 +36,21 @@ ruleTester.run('no-color-css-vars', rule, { } ] }, - { - code: ``, - output: ``, - errors: [ - { - message: 'Replace var(--color-accent-fg) with accent.fg' - } - ] - }, + // { + // code: ``, + // output: ``, + // errors: [ + // { + // message: 'Replace var(--color-accent-fg) with accent.fg' + // } + // ] + // }, { code: ``, output: ``, @@ -95,8 +104,8 @@ ruleTester.run('no-color-css-vars', rule, { message: 'Replace var(--color-canvas-default) with canvas.default' } ] - }, - // { + } + //{ // code: `import {sx, SxProp} from '@primer/react' export const HighlightToken = styled.span < SxProp > \`color: var(--color-accent-emphasis); ${sx}\` const ClickableTokenSpan = styled(HighlightToken)\` &:hover, &:focus { background-color: accent.muted;}\``, // output: `import {sx, SxProp} from '@primer/react' export const HighlightToken = styled.span < SxProp > \`color: accent.emphasis; ${sx}\` const ClickableTokenSpan = styled(HighlightToken)\` &:hover, &:focus { background-color: accent.muted;}\``, // errors: [ @@ -105,14 +114,5 @@ ruleTester.run('no-color-css-vars', rule, { // } // ] // } - { - code: ``, - output: ``, - errors: [ - { - message: 'Replace var(--color-border-default) with border.default' - } - ] - } ] }) diff --git a/src/rules/__tests__/no-css-vars.test.js b/src/rules/__tests__/no-css-vars.test.js deleted file mode 100644 index 386eda78..00000000 --- a/src/rules/__tests__/no-css-vars.test.js +++ /dev/null @@ -1,43 +0,0 @@ -const rule = require('../no-css-vars') -const {RuleTester} = require('eslint') - -const ruleTester = new RuleTester({ - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - ecmaFeatures: { - jsx: true - } - } -}) - -// report all strings that start with 'var(--color-' -// autofix strings: 'var(--color-fg-default)' -> 'fg.default' - -{ - /* + // `, + // output: ` + // const styles = { color: 'fg.muted' } + // export const Fixture = + // `, + // errors: [ + // { + // message: 'Replace var(--color-fg-muted) with fg.muted' + // } + // ] // } ] }) From c2774e5f4f837f3a9918c6dd3360490a097c8698 Mon Sep 17 00:00:00 2001 From: Siddharth Kshetrapal Date: Wed, 28 Jun 2023 01:52:50 +0200 Subject: [PATCH 08/18] upgrade eslint version to 8.42 --- package-lock.json | 404 +++++++++++++++++++++++++++++++++------------- package.json | 4 +- 2 files changed, 296 insertions(+), 112 deletions(-) diff --git a/package-lock.json b/package-lock.json index a27f065f..b42f137c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,12 +21,12 @@ "@changesets/cli": "^2.16.0", "@github/prettier-config": "0.0.4", "@primer/primitives": "^5.1.0", - "eslint": "^8.0.1", + "eslint": "^8.42.0", "jest": "^27.0.6" }, "peerDependencies": { "@primer/primitives": ">=4.6.2", - "eslint": "^8.0.1" + "eslint": "^8.42.0" } }, "node_modules/@babel/code-frame": { @@ -1167,15 +1167,37 @@ "prettier": "^1.19.1" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", + "espree": "^9.5.2", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -1184,6 +1206,9 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/eslintrc/node_modules/argparse": { @@ -1192,9 +1217,9 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dependencies": { "type-fest": "^0.20.2" }, @@ -1227,6 +1252,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/js": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", + "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@github/prettier-config": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/@github/prettier-config/-/prettier-config-0.0.4.tgz", @@ -1234,18 +1267,30 @@ "dev": true }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -3534,33 +3579,39 @@ } }, "node_modules/eslint": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz", - "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==", - "dependencies": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", + "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.43.0", + "@humanwhocodes/config-array": "^0.11.10", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -3568,11 +3619,9 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -3904,15 +3953,18 @@ } }, "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-traverse": { @@ -3946,11 +3998,14 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/argparse": { @@ -3969,6 +4024,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -3981,9 +4051,9 @@ } }, "node_modules/eslint/node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dependencies": { "type-fest": "^0.20.2" }, @@ -4017,6 +4087,20 @@ "node": ">= 0.8.0" } }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -4033,6 +4117,34 @@ "node": ">= 0.8.0" } }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -4064,16 +4176,19 @@ } }, "node_modules/espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", "dependencies": { - "acorn": "^8.7.1", + "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -4090,9 +4205,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dependencies": { "estraverse": "^5.1.0" }, @@ -4541,6 +4656,11 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -4932,6 +5052,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -6530,7 +6658,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "engines": { "node": ">=8" } @@ -7930,11 +8057,6 @@ "punycode": "^2.1.0" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" - }, "node_modules/v8-to-istanbul": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz", @@ -8268,7 +8390,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "engines": { "node": ">=10" }, @@ -9217,15 +9338,28 @@ "prettier": "^1.19.1" } }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==" + }, "@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", + "espree": "^9.5.2", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -9239,9 +9373,9 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "requires": { "type-fest": "^0.20.2" } @@ -9261,6 +9395,11 @@ } } }, + "@eslint/js": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", + "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==" + }, "@github/prettier-config": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/@github/prettier-config/-/prettier-config-0.0.4.tgz", @@ -9268,15 +9407,20 @@ "dev": true }, "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "requires": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" } }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==" + }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -11042,33 +11186,39 @@ } }, "eslint": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz", - "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==", - "requires": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", + "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.43.0", + "@humanwhocodes/config-array": "^0.11.10", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -11076,11 +11226,9 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "dependencies": { "argparse": { @@ -11093,6 +11241,15 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, "glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -11102,9 +11259,9 @@ } }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "requires": { "type-fest": "^0.20.2" } @@ -11126,6 +11283,14 @@ "type-check": "~0.4.0" } }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "requires": { + "p-locate": "^5.0.0" + } + }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -11139,6 +11304,22 @@ "word-wrap": "^1.2.3" } }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "requires": { + "p-limit": "^3.0.2" + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -11398,9 +11579,9 @@ "integrity": "sha512-pWReu3fkohwyvztx/oQWWgld2iad25TfUdi6wvhhaDPIQjHU/pyvlKgXFw1kX31SQK2Nq9MH+vRDWB0ZLy8fYw==" }, "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "requires": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -11427,18 +11608,18 @@ } }, "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==" + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==" }, "espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", "requires": { - "acorn": "^8.7.1", + "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" } }, "esprima": { @@ -11448,9 +11629,9 @@ "dev": true }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "requires": { "estraverse": "^5.1.0" } @@ -11789,6 +11970,11 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + }, "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -12059,6 +12245,11 @@ "has-tostringtag": "^1.0.0" } }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" + }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -13281,8 +13472,7 @@ "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-is-absolute": { "version": "1.0.1", @@ -14327,11 +14517,6 @@ "punycode": "^2.1.0" } }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" - }, "v8-to-istanbul": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz", @@ -14594,8 +14779,7 @@ "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" } } } diff --git a/package.json b/package.json index acbe1e9e..2e77c439 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,12 @@ "@changesets/cli": "^2.16.0", "@github/prettier-config": "0.0.4", "@primer/primitives": "^5.1.0", - "eslint": "^8.0.1", + "eslint": "^8.42.0", "jest": "^27.0.6" }, "peerDependencies": { "@primer/primitives": ">=4.6.2", - "eslint": "^8.0.1" + "eslint": "^8.42.0" }, "prettier": "@github/prettier-config", "dependencies": { From 108b8b5bc8c2f8acdb1e62983ef04dab7948a957 Mon Sep 17 00:00:00 2001 From: Siddharth Kshetrapal Date: Wed, 28 Jun 2023 01:54:23 +0200 Subject: [PATCH 09/18] handle identifiers, add more test cases --- src/rules/__tests__/no-color-css-vars.test.js | 59 +++++++++++++++++-- src/rules/no-color-css-vars.js | 24 +++++++- 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/src/rules/__tests__/no-color-css-vars.test.js b/src/rules/__tests__/no-color-css-vars.test.js index 3abf2683..3d90c039 100644 --- a/src/rules/__tests__/no-color-css-vars.test.js +++ b/src/rules/__tests__/no-color-css-vars.test.js @@ -110,8 +110,41 @@ ruleTester.run('no-color-css-vars', rule, { message: 'Replace var(--color-canvas-default) with canvas.default' } ] + }, + { + name: 'variable in scope', + code: ` + const baseStyles = { color: 'var(--color-fg-muted)' } + export const Fixture = + `, + output: ` + const baseStyles = { color: 'fg.muted' } + export const Fixture = + `, + errors: [ + { + message: 'Replace var(--color-fg-muted) with fg.muted' + } + ] + }, + { + name: 'merge in sx', + code: ` + import {merge} from '@primer/react' + export const Fixture = props => + `, + output: ` + import {merge} from '@primer/react' + export const Fixture = props => + `, + errors: [ + { + message: 'Replace var(--color-fg-muted) with fg.muted' + } + ] } // { + // name: 'variable in styled.component', // code: ` // import {sx, SxProp} from '@primer/react' // export const HighlightToken = styled.span\` @@ -138,15 +171,31 @@ ruleTester.run('no-color-css-vars', rule, { // } // ] // }, - // { + // name: 'MemberExpression in sx: not handled', + // code: ` + // const colors = { muted: 'var(--color-fg-muted)' } + // export const Fixture = + // `, + // output: ` + // const colors = { muted: 'fg.muted' } + // export const Fixture = + // `, + // errors: [ + // { + // message: 'Replace var(--color-fg-muted) with fg.muted' + // } + // ] + // }, + // { + // name: 'CallExpression in sx: not handled', // code: ` - // const styles = { color: 'var(--color-fg-muted)' } - // export const Fixture = + // const getColors = () => 'var(--color-fg-muted)' + // export const Fixture = // `, // output: ` - // const styles = { color: 'fg.muted' } - // export const Fixture = + // const getColors = () => 'fg.muted' + // export const Fixture = // `, // errors: [ // { diff --git a/src/rules/no-color-css-vars.js b/src/rules/no-color-css-vars.js index efdef64d..ff1099d4 100644 --- a/src/rules/no-color-css-vars.js +++ b/src/rules/no-color-css-vars.js @@ -23,6 +23,7 @@ module.exports = { } ] }, + /** @param {import('eslint').Rule.RuleContext} context */ create(context) { const styledSystemProps = [ 'bg', @@ -39,10 +40,29 @@ module.exports = { ] return { + /** @param {import('eslint').Rule.Node} node */ JSXAttribute(node) { if (node.name.name === 'sx') { - const rawText = context.getSourceCode().getText(node.value) - checkForVariables(node.value, rawText) + if (node.value.expression.type === 'ObjectExpression') { + // example: sx={{ color: 'fg.default' }} or sx={{ ':hover': {color: 'fg.default'} }} + const rawText = context.sourceCode.getText(node.value) + checkForVariables(node.value, rawText) + } else if (node.value.expression.type === 'Identifier') { + // example: sx={baseStyles} + const variableScope = context.sourceCode.getScope(node.value.expression) + const variable = variableScope.set.get(node.value.expression.name) + + // if variable is not defined in scope, give up (could be imported from different file) + if (!variable) return + + const variableDeclarator = variable.identifiers[0].parent + const rawText = context.sourceCode.getText(variableDeclarator) + checkForVariables(variableDeclarator, rawText) + } else { + // worth a try! + const rawText = context.sourceCode.getText(node.value) + checkForVariables(node.value, rawText) + } } else if ( styledSystemProps.includes(node.name.name) && node.value.type === 'Literal' && From bf51fb4fbfc9aaf658b6490615a58c82895b69fe Mon Sep 17 00:00:00 2001 From: langermank <18661030+langermank@users.noreply.github.com> Date: Mon, 25 Sep 2023 12:32:36 -0700 Subject: [PATCH 10/18] use css vars --- package-lock.json | 14 +- package.json | 2 +- src/rules/__tests__/no-color-css-vars.test.js | 108 +- src/rules/no-color-css-vars.js | 37 +- src/utils/css-variable-map.json | 2065 +++++++++++++++++ 5 files changed, 2147 insertions(+), 79 deletions(-) create mode 100644 src/utils/css-variable-map.json diff --git a/package-lock.json b/package-lock.json index b42f137c..b7b7552a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "@changesets/changelog-github": "^0.4.0", "@changesets/cli": "^2.16.0", "@github/prettier-config": "0.0.4", - "@primer/primitives": "^5.1.0", + "@primer/primitives": "^7.14.0", "eslint": "^8.42.0", "jest": "^27.0.6" }, @@ -1653,9 +1653,9 @@ } }, "node_modules/@primer/primitives": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@primer/primitives/-/primitives-5.1.0.tgz", - "integrity": "sha512-pW8DIh6rZV0/R7lxHnVRJ/tdN4kDVSpAtdcCecxKsvtgK5d9haekt3ERpM6i93xKwB5CJYy9ouuC9C0UqWPI0A==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@primer/primitives/-/primitives-7.14.0.tgz", + "integrity": "sha512-M5to3Csxr+t1EXfRjQOe5MuMjCTiziMC+O3gCp+K8apbL07ZvqcIDHdYvcNvFCP4NX1Uj6caPE8VdguqBTSgSg==", "dev": true }, "node_modules/@sinonjs/commons": { @@ -9717,9 +9717,9 @@ } }, "@primer/primitives": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@primer/primitives/-/primitives-5.1.0.tgz", - "integrity": "sha512-pW8DIh6rZV0/R7lxHnVRJ/tdN4kDVSpAtdcCecxKsvtgK5d9haekt3ERpM6i93xKwB5CJYy9ouuC9C0UqWPI0A==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@primer/primitives/-/primitives-7.14.0.tgz", + "integrity": "sha512-M5to3Csxr+t1EXfRjQOe5MuMjCTiziMC+O3gCp+K8apbL07ZvqcIDHdYvcNvFCP4NX1Uj6caPE8VdguqBTSgSg==", "dev": true }, "@sinonjs/commons": { diff --git a/package.json b/package.json index 2e77c439..1a799bfa 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "@changesets/changelog-github": "^0.4.0", "@changesets/cli": "^2.16.0", "@github/prettier-config": "0.0.4", - "@primer/primitives": "^5.1.0", + "@primer/primitives": "^7.14.0", "eslint": "^8.42.0", "jest": "^27.0.6" }, diff --git a/src/rules/__tests__/no-color-css-vars.test.js b/src/rules/__tests__/no-color-css-vars.test.js index 3d90c039..2bf1aeb3 100644 --- a/src/rules/__tests__/no-color-css-vars.test.js +++ b/src/rules/__tests__/no-color-css-vars.test.js @@ -29,10 +29,10 @@ ruleTester.run('no-color-css-vars', rule, { invalid: [ { code: ``, - output: ``, + output: ``, errors: [ { - message: 'Replace var(--color-fg-muted) with fg.muted' + message: 'Replace var(--color-fg-muted) with var(--fgColor-muted, var(--color-fg-muted))' } ] }, @@ -47,67 +47,40 @@ ruleTester.run('no-color-css-vars', rule, { output: ` `, errors: [ { - message: 'Replace var(--color-accent-fg) with accent.fg' + message: 'Replace var(--color-accent-fg) with var(--fgColor-accent, var(--color-accent-fg))' } ] }, { code: ``, - output: ``, + output: ``, errors: [ { - message: 'Replace var(--color-canvas-subtle) with canvas.subtle' + message: 'Replace var(--color-canvas-subtle) with var(--bgColor-muted, var(--color-canvas-subtle))' } ] }, { code: ``, - output: ``, + output: ``, errors: [ { - message: 'Replace var(--color-border-default) with border.default' - } - ] - }, - { - code: ``, - output: ``, - errors: [ - { - message: 'Replace var(--color-border-default) with border.default' + message: 'Replace var(--color-border-default) with var(--borderColor-default, var(--color-border-default))' } ] }, { code: ``, - output: ``, - errors: [ - { - message: 'Replace var(--color-canvas-default) with canvas.default' - } - ] - }, - { - code: ``, - output: ``, - errors: [ - { - message: 'Replace var(--color-canvas-default) with canvas.default' - } - ] - }, - { - code: ``, - output: ``, + output: ``, errors: [ { - message: 'Replace var(--color-canvas-default) with canvas.default' + message: 'Replace var(--color-canvas-default) with var(--bgColor-default, var(--color-canvas-default))' } ] }, @@ -118,12 +91,12 @@ ruleTester.run('no-color-css-vars', rule, { export const Fixture = `, output: ` - const baseStyles = { color: 'fg.muted' } + const baseStyles = { color: 'var(--fgColor-muted, var(--color-fg-muted))' } export const Fixture = `, errors: [ { - message: 'Replace var(--color-fg-muted) with fg.muted' + message: 'Replace var(--color-fg-muted) with var(--fgColor-muted, var(--color-fg-muted))' } ] }, @@ -135,14 +108,24 @@ ruleTester.run('no-color-css-vars', rule, { `, output: ` import {merge} from '@primer/react' - export const Fixture = props => + export const Fixture = props => `, errors: [ { - message: 'Replace var(--color-fg-muted) with fg.muted' + message: 'Replace var(--color-fg-muted) with var(--fgColor-muted, var(--color-fg-muted))' + } + ] + }, + { + code: ``, + output: ``, + errors: [ + { + message: 'Replace var(--color-border-default) with var(--borderColor-default, var(--color-border-default))' } ] } + // broken tests start below // { // name: 'variable in styled.component', // code: ` @@ -158,7 +141,7 @@ ruleTester.run('no-color-css-vars', rule, { // output: ` // import {sx, SxProp} from '@primer/react' // export const HighlightToken = styled.span\` - // color: accent.emphasis; + // color: var(--bgColor-accent-emphasis, var(--color-accent-emphasis)); // \${sx} // \` // const ClickableTokenSpan = styled(HighlightToken)\` @@ -167,10 +150,11 @@ ruleTester.run('no-color-css-vars', rule, { // `, // errors: [ // { - // message: 'Replace var(--color-accent-emphasis) with accent.emphasis' + // message: + // 'Replace var(--color-accent-emphasis) with var(--bgColor-accent-emphasis, var(--color-accent-emphasis))' // } // ] - // }, + // } // { // name: 'MemberExpression in sx: not handled', // code: ` @@ -178,30 +162,30 @@ ruleTester.run('no-color-css-vars', rule, { // export const Fixture = // `, // output: ` - // const colors = { muted: 'fg.muted' } + // const colors = { muted: 'var(--fgColor-muted, var(--color-fg-muted))' } // export const Fixture = // `, // errors: [ // { - // message: 'Replace var(--color-fg-muted) with fg.muted' - // } - // ] - // }, - // { - // name: 'CallExpression in sx: not handled', - // code: ` - // const getColors = () => 'var(--color-fg-muted)' - // export const Fixture = - // `, - // output: ` - // const getColors = () => 'fg.muted' - // export const Fixture = - // `, - // errors: [ - // { - // message: 'Replace var(--color-fg-muted) with fg.muted' + // message: 'Replace var(--color-fg-muted) with var(--fgColor-muted, var(--color-fg-muted))' // } // ] // } + // { + // name: 'CallExpression in sx: not handled', + // code: ` + // const getColors = () => 'var(--color-fg-muted)' + // export const Fixture = + // `, + // output: ` + // const getColors = () => 'var(--fgColor-muted, var(--color-fg-muted))' + // export const Fixture = + // `, + // errors: [ + // { + // message: 'Replace var(--color-fg-muted) with var(--fgColor-muted, var(--color-fg-muted))' + // } + // ] + // } ] }) diff --git a/src/rules/no-color-css-vars.js b/src/rules/no-color-css-vars.js index ff1099d4..01399710 100644 --- a/src/rules/no-color-css-vars.js +++ b/src/rules/no-color-css-vars.js @@ -1,4 +1,4 @@ -const cssVars = require('../utils/css-var-map.json') +const cssVars = require('../utils/css-variable-map.json') module.exports = { meta: { @@ -77,15 +77,34 @@ module.exports = { // performance optimisation: exit early if (!rawText.includes('var')) return - Object.keys(cssVars).forEach(cssVar => { - if (rawText.includes(`var(${cssVar}`)) { - const fixedString = rawText.replace(`var(${cssVar})`, cssVars[cssVar]) + // Object.keys(cssVars).forEach(cssVar => { + // if (rawText.includes(`var(${cssVar}`)) { + // const fixedString = rawText.replace(`var(${cssVar})`, cssVars[cssVar]) + + // context.report({ + // node, + // message: `Replace var(${cssVar}) with ${cssVars[cssVar]}`, + // fix: function(fixer) { + // return fixer.replaceText(node, node.type === 'Literal' ? `"${fixedString}"` : fixedString) + // } + // }) + // } + // }) - context.report({ - node, - message: `Replace var(${cssVar}) with ${cssVars[cssVar]}`, - fix: function(fixer) { - return fixer.replaceText(node, node.type === 'Literal' ? `"${fixedString}"` : fixedString) + console.log('Rule is being executed') + Object.keys(cssVars).forEach(cssVar => { + if (Array.isArray(cssVars[cssVar])) { + cssVars[cssVar].forEach(cssVarObject => { + const regex = new RegExp(`var\\(${cssVar}\\)`, 'g') + if (cssVarObject.props.some(prop => rawText.includes(prop)) && regex.test(rawText)) { + const fixedString = rawText.replace(regex, `var(${cssVarObject.replacement}, var(${cssVar}))`) + context.report({ + node, + message: `Replace var(${cssVar}) with var(${cssVarObject.replacement}, var(${cssVar}))`, + fix: function(fixer) { + return fixer.replaceText(node, node.type === 'Literal' ? `"${fixedString}"` : fixedString) + } + }) } }) } diff --git a/src/utils/css-variable-map.json b/src/utils/css-variable-map.json new file mode 100644 index 00000000..ddaf551c --- /dev/null +++ b/src/utils/css-variable-map.json @@ -0,0 +1,2065 @@ +{ + "--color-page-header-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--page-header-bgColor" + } + ], + "--color-diff-blob-addition-num-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--diffBlob-addition-fgColor-num" + } + ], + "--color-diff-blob-addition-fg": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--diffBlob-addition-fgColor-text" + } + ], + "--color-diff-blob-addition-num-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--diffBlob-addition-bgColor-num" + } + ], + "--color-diff-blob-addition-line-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--diffBlob-addition-bgColor-line" + } + ], + "--color-diff-blob-addition-word-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--diffBlob-addition-bgColor-word" + } + ], + "--color-diff-blob-deletion-num-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--diffBlob-deletion-fgColor-num" + } + ], + "--color-diff-blob-deletion-fg": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--diffBlob-deletion-fgColor-text" + } + ], + "--color-diff-blob-deletion-num-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--diffBlob-deletion-bgColor-num" + } + ], + "--color-diff-blob-deletion-line-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--diffBlob-deletion-bgColor-line" + } + ], + "--color-diff-blob-deletion-word-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--diffBlob-deletion-bgColor-word" + } + ], + "--color-diff-blob-hunk-num-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--diffBlob-hunk-bgColor-num" + } + ], + "--color-diff-blob-expander-icon": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--diffBlob-expander-iconColor" + } + ], + "--color-diffstat-deletion-border": [], + "--color-diffstat-addition-border": [], + "--color-diffstat-addition-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--diffStat-addition-bgColor" + } + ], + "--color-search-keyword-hl": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--highlight-neutral-bgColor" + } + ], + "--color-codemirror-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--codeMirror-fgColor" + } + ], + "--color-codemirror-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--codeMirror-bgColor" + } + ], + "--color-codemirror-gutters-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--codeMirror-gutters-bgColor" + } + ], + "--color-codemirror-guttermarker-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--codeMirror-gutterMarker-fgColor-default" + } + ], + "--color-codemirror-guttermarker-subtle-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--codeMirror-gutterMarker-fgColor-muted" + } + ], + "--color-codemirror-linenumber-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--codeMirror-lineNumber-fgColor" + } + ], + "--color-codemirror-cursor": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--codeMirror-cursor-fgColor" + } + ], + "--color-codemirror-selection-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--codeMirror-selection-bgColor" + } + ], + "--color-codemirror-activeline-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--codeMirror-activeline-bgColor" + } + ], + "--color-codemirror-matchingbracket-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--codeMirror-matchingBracket-fgColor" + } + ], + "--color-codemirror-lines-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--codeMirror-lines-bgColor" + } + ], + "--color-codemirror-syntax-comment": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--codeMirror-syntax-fgColor-comment" + } + ], + "--color-codemirror-syntax-constant": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--codeMirror-syntax-fgColor-constant" + } + ], + "--color-codemirror-syntax-entity": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--codeMirror-syntax-fgColor-entity" + } + ], + "--color-codemirror-syntax-keyword": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--codeMirror-syntax-fgColor-keyword" + } + ], + "--color-codemirror-syntax-storage": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--codeMirror-syntax-fgColor-storage" + } + ], + "--color-codemirror-syntax-string": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--codeMirror-syntax-fgColor-string" + } + ], + "--color-codemirror-syntax-support": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--codeMirror-syntax-fgColor-support" + } + ], + "--color-codemirror-syntax-variable": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--codeMirror-syntax-fgColor-variable" + } + ], + "--color-header-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--header-fgColor-default" + } + ], + "--color-header-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--header-bgColor" + } + ], + "--color-header-divider": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg", + "color" + ], + "replacement": "--header-borderColor-divider" + } + ], + "--color-header-logo": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--header-fgColor-logo" + } + ], + "--color-header-search-bg": [ + { + "props": ["backgroundColor", "bg", "background-color"], + "replacement": "--headerSearch-bgColor" + } + ], + "--color-header-search-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--headerSearch-borderColor" + } + ], + "--color-avatar-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--avatar-bgColor" + } + ], + "--color-avatar-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg", + "boxShadow" + ], + "replacement": "--avatar-borderColor" + } + ], + "--color-avatar-stack-fade": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--avatarStack-fade-bgColor-default" + } + ], + "--color-avatar-stack-fade-more": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--avatarStack-fade-bgColor-muted" + } + ], + "--color-topic-tag-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--topicTag-borderColor" + } + ], + "--color-counter-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--counter-borderColor" + } + ], + "--color-select-menu-backdrop-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--selectMenu-borderColor" + } + ], + "--color-select-menu-tap-highlight": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--control-bgColor-active" + } + ], + "--color-select-menu-tap-focus-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--selectMenu-bgColor-active" + } + ], + "--color-sidenav-selected-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--sideNav-bgColor-selected" + } + ], + "--color-menu-bg-active": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--menu-bgColor-active" + } + ], + "--color-input-disabled-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--control-bgColor-disabled" + } + ], + "--color-timeline-badge-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--timelineBadge-bgColor" + } + ], + "--color-btn-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--button-default-bgColor-rest" + } + ], + "--color-btn-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--button-default-borderColor-rest" + } + ], + "--color-btn-hover-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--button-default-bgColor-hover" + } + ], + "--color-btn-hover-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--button-default-borderColor-hover" + } + ], + "--color-btn-active-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--button-default-bgColor-active" + } + ], + "--color-btn-active-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--button-default-borderColor-active" + } + ], + "--color-btn-selected-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--button-default-bgColor-selected" + } + ], + "--color-btn-counter-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--buttonCounter-default-bgColor-rest" + } + ], + "--color-btn-primary-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--button-primary-fgColor-rest" + } + ], + "--color-btn-primary-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--button-primary-bgColor-rest" + } + ], + "--color-btn-primary-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--button-primary-borderColor-rest" + } + ], + "--color-btn-primary-hover-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--button-primary-bgColor-hover" + } + ], + "--color-btn-primary-hover-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--button-primary-borderColor-hover" + } + ], + "--color-btn-primary-selected-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--button-primary-bgColor-active" + } + ], + "--color-btn-primary-disabled-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--button-primary-fgColor-disabled" + } + ], + "--color-btn-primary-disabled-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--button-primary-bgColor-disabled" + } + ], + "--color-btn-primary-disabled-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--button-primary-borderColor-disabled" + } + ], + "--color-btn-primary-icon": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--button-primary-iconColor-rest" + } + ], + "--color-btn-primary-counter-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--buttonCounter-primary-bgColor-rest" + } + ], + "--color-btn-outline-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--button-outline-fgColor-rest" + } + ], + "--color-btn-outline-hover-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--button-outline-fgColor-hover" + } + ], + "--color-btn-outline-hover-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--button-outline-bgColor-hover" + } + ], + "--color-btn-outline-hover-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--button-outline-borderColor-hover" + } + ], + "--color-btn-outline-hover-counter-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--buttonCounter-outline-bgColor-hover" + } + ], + "--color-btn-outline-selected-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--button-outline-fgColor-active" + } + ], + "--color-btn-outline-selected-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--button-outline-bgColor-active" + } + ], + "--color-btn-outline-selected-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--button-outline-borderColor-active" + } + ], + "--color-btn-outline-disabled-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--button-outline-fgColor-disabled" + } + ], + "--color-btn-outline-disabled-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--button-outline-bgColor-disabled" + } + ], + "--color-btn-outline-disabled-counter-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--buttonCounter-outline-bgColor-disabled" + } + ], + "--color-btn-outline-counter-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--buttonCounter-outline-bgColor-rest" + } + ], + "--color-btn-danger-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--button-danger-fgColor-rest" + } + ], + "--color-btn-danger-hover-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--button-danger-fgColor-hover" + } + ], + "--color-btn-danger-hover-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--button-danger-bgColor-hover" + } + ], + "--color-btn-danger-hover-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--button-danger-borderColor-hover" + } + ], + "--color-btn-danger-hover-counter-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--buttonCounter-danger-bgColor-hover" + } + ], + "--color-btn-danger-selected-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--button-danger-fgColor-active" + } + ], + "--color-btn-danger-selected-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--button-danger-bgColor-active" + } + ], + "--color-btn-danger-selected-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--button-danger-borderColor-active" + } + ], + "--color-btn-danger-disabled-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--button-danger-fgColor-disabled" + } + ], + "--color-btn-danger-disabled-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--button-danger-bgColor-disabled" + } + ], + "--color-btn-danger-disabled-counter-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--buttonCounter-danger-bgColor-disabled" + } + ], + "--color-btn-danger-counter-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--buttonCounter-danger-bgColor-rest" + } + ], + "--color-btn-danger-icon": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--button-danger-iconColor-rest" + } + ], + "--color-btn-danger-hover-icon": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--button-danger-iconColor-hover" + } + ], + "--color-underlinenav-icon": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--underlineNav-iconColor-rest" + } + ], + "--color-underlinenav-border-hover": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--underlineNav-borderColor-hover" + } + ], + "--color-action-list-item-inline-divider": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--borderColor-muted" + } + ], + "--color-action-list-item-default-hover-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--control-transparent-bgColor-hover" + } + ], + "--color-action-list-item-default-hover-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--control-transparent-borderColor-hover" + } + ], + "--color-action-list-item-default-active-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--control-transparent-bgColor-active" + } + ], + "--color-action-list-item-default-active-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--control-transparent-borderColor-active" + } + ], + "--color-action-list-item-default-selected-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--control-transparent-bgColor-selected" + } + ], + "--color-action-list-item-danger-hover-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--control-danger-bgColor-hover" + } + ], + "--color-action-list-item-danger-active-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--control-danger-bgColor-active" + } + ], + "--color-action-list-item-danger-hover-text": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--control-danger-fgColor-hover" + } + ], + "--color-switch-track-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--controlTrack-bgColor-rest" + } + ], + "--color-switch-track-hover-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--controlTrack-bgColor-hover" + } + ], + "--color-switch-track-active-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--controlTrack-bgColor-active" + } + ], + "--color-switch-track-disabled-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--controlTrack-bgColor-disabled" + } + ], + "--color-switch-track-fg": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--controlTrack-fgColor-rest" + } + ], + "--color-switch-track-disabled-fg": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--controlTrack-fgColor-disabled" + } + ], + "--color-switch-track-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--controlTrack-borderColor-rest" + } + ], + "--color-switch-track-checked-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--control-checked-bgColor-rest" + } + ], + "--color-switch-track-checked-hover-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--control-checked-bgColor-hover" + } + ], + "--color-switch-track-checked-active-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--control-checked-bgColor-active" + } + ], + "--color-switch-track-checked-fg": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--control-checked-fgColor-rest" + } + ], + "--color-switch-track-checked-disabled-fg": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--control-checked-fgColor-disabled" + } + ], + "--color-switch-track-checked-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow" + ], + "replacement": "--borderColor-transparent" + } + ], + "--color-switch-knob-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--controlKnob-bgColor-rest" + } + ], + "--color-switch-knob-disabled-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--controlKnob-bgColor-disabled" + } + ], + "--color-switch-knob-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--controlKnob-borderColor-rest" + } + ], + "--color-switch-knob-checked-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--controlKnob-bgColor-checked" + } + ], + "--color-switch-knob-checked-disabled-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--controlKnob-bgColor-disabled" + } + ], + "--color-switch-knob-checked-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--controlKnob-borderColor-checked" + } + ], + "--color-segmented-control-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--controlTrack-bgColor-rest" + } + ], + "--color-segmented-control-button-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--controlKnob-bgColor-rest" + } + ], + "--color-segmented-control-button-hover-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--controlTrack-bgColor-hover" + } + ], + "--color-segmented-control-button-active-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--controlTrack-bgColor-active" + } + ], + "--color-segmented-control-button-selected-border": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--controlKnob-borderColor-rest" + } + ], + "--color-tree-view-item-chevron-hover-bg": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--control-transparent-bgColor-hover" + } + ], + "--color-tree-view-item-directory-fill": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--treeViewItem-leadingVisual-bgColor-rest" + } + ], + "--color-canvas-default-transparent": [ + { + "props": ["backgroundColor", "bg", "color"], + "replacement": "--bgColor-transparent" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow" + ], + "replacement": "--borderColor-transparent" + } + ], + "--color-fg-default": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--fgColor-default" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--fgColor-default" + } + ], + "--color-fg-muted": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--fgColor-muted" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-neutral-emphasis" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow" + ], + "replacement": "--borderColor-neutral-emphasis" + } + ], + "--color-fg-subtle": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--fgColor-muted" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow" + ], + "replacement": "--borderColor-neutral-emphasis" + } + ], + "--color-fg-on-emphasis": [ + { + "props": [ + "color", + "fill", + "caretColor", + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow" + ], + "replacement": "--fgColor-onEmphasis" + } + ], + "--color-canvas-default": [ + { + "props": [ + "backgroundColor", + "bg", + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "boxShadow", + "fill", + "stroke" + ], + "replacement": "--bgColor-default" + } + ], + "--color-canvas-overlay": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--overlay-bgColor" + } + ], + "--color-canvas-inset": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-inset" + } + ], + "--color-canvas-subtle": [ + { + "props": [ + "backgroundColor", + "bg", + "fill", + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow" + ], + "replacement": "--bgColor-muted" + } + ], + "--color-border-default": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "backgroundColor", + "bg", + "boxShadow", + "stroke", + "outline", + "fill" + ], + "replacement": "--borderColor-default" + } + ], + "--color-border-muted": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "backgroundColor", + "bg", + "outline", + "boxShadow", + "stroke" + ], + "replacement": "--borderColor-muted" + } + ], + "--color-border-subtle": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg", + "outline" + ], + "replacement": "--borderColor-muted" + } + ], + "--color-neutral-emphasis-plus": [ + { + "props": [ + "backgroundColor", + "bg", + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "color", + "stroke" + ], + "replacement": "--bgColor-emphasis" + } + ], + "--color-neutral-emphasis": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-neutral-emphasis" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "boxShadow" + ], + "replacement": "--borderColor-neutral-emphasis" + }, + { + "props": ["color", "fill", "caretColor"], + "replacement": "--fgColor-neutral" + } + ], + "--color-neutral-muted": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "boxShadow" + ], + "replacement": "--borderColor-neutral-muted" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-neutral-muted" + } + ], + "--color-neutral-subtle": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-neutral-muted" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "boxShadow" + ], + "replacement": "--borderColor-neutral-muted" + } + ], + "--color-accent-fg": [ + { + "props": ["color", "fill", "caretColor", "stroke"], + "replacement": "--fgColor-accent" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "boxShadow" + ], + "replacement": "--borderColor-accent-emphasis" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-accent-emphasis" + }, + { + "props": ["outline"], + "replacement": "--focus-outlineColor" + } + ], + "--color-accent-emphasis": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-accent-emphasis" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "boxShadow" + ], + "replacement": "--borderColor-accent-emphasis" + }, + { + "props": ["color", "fill", "caretColor", "stroke"], + "replacement": "--fgColor-accent" + }, + { + "props": ["outline"], + "replacement": "--focus-outlineColor" + } + ], + "--color-accent-muted": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "boxShadow" + ], + "replacement": "--borderColor-accent-muted" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-accent-muted" + } + ], + "--color-accent-subtle": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-accent-muted" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "boxShadow" + ], + "replacement": "--borderColor-accent-muted" + } + ], + "--color-success-fg": [ + { + "props": ["color", "fill", "caretColor", "stroke"], + "replacement": "--fgColor-success" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-success-emphasis" + } + ], + "--color-success-emphasis": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-success-emphasis" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow" + ], + "replacement": "--borderColor-success-emphasis" + }, + { + "props": ["color"], + "replacement": "--fgColor-success" + } + ], + "--color-success-muted": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow" + ], + "replacement": "--borderColor-success-muted" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-success-muted" + } + ], + "--color-success-subtle": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-success-muted" + } + ], + "--color-attention-fg": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--fgColor-attention" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-attention-emphasis" + } + ], + "--color-attention-emphasis": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-attention-emphasis" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow" + ], + "replacement": "--borderColor-attention-emphasis" + }, + { + "props": ["color", "fill", "caretColor"], + "replacement": "--fgColor-attention" + } + ], + "--color-attention-muted": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "boxShadow" + ], + "replacement": "--borderColor-attention-muted" + } + ], + "--color-attention-subtle": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-attention-muted" + } + ], + "--color-severe-fg": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--fgColor-severe" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-severe-emphasis" + } + ], + "--color-severe-emphasis": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-severe-emphasis" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "boxShadow" + ], + "replacement": "--borderColor-severe-emphasis" + }, + { + "props": ["color", "fill", "caretColor", "stroke"], + "replacement": "--fgColor-severe" + } + ], + "--color-severe-muted": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "boxShadow" + ], + "replacement": "--borderColor-severe-muted" + } + ], + "--color-severe-subtle": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-severe-muted" + } + ], + "--color-danger-fg": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--fgColor-danger" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-danger-emphasis" + } + ], + "--color-danger-emphasis": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-danger-emphasis" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "boxShadow", + "outline" + ], + "replacement": "--borderColor-danger-emphasis" + }, + { + "props": ["color", "fill", "caretColor"], + "replacement": "--fgColor-danger" + } + ], + "--color-danger-muted": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "boxShadow" + ], + "replacement": "--borderColor-danger-muted" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-danger-muted" + } + ], + "--color-danger-subtle": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-danger-muted" + } + ], + "--color-open-fg": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--fgColor-open" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-open-emphasis" + } + ], + "--color-open-emphasis": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-open-emphasis" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "boxShadow" + ], + "replacement": "--borderColor-open-emphasis" + }, + { + "props": ["color"], + "replacement": "--fgColor-open" + } + ], + "--color-open-muted": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "boxShadow" + ], + "replacement": "--borderColor-open-muted" + } + ], + "--color-open-subtle": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-open-muted" + } + ], + "--color-closed-fg": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--fgColor-closed" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-closed-emphasis" + } + ], + "--color-closed-emphasis": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-closed-emphasis" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "boxShadow" + ], + "replacement": "--borderColor-closed-emphasis" + }, + { + "props": ["color"], + "replacement": "--fgColor-closed" + } + ], + "--color-closed-muted": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "boxShadow" + ], + "replacement": "--borderColor-closed-muted" + } + ], + "--color-closed-subtle": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-closed-muted" + } + ], + "--color-done-fg": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--fgColor-done" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-done-emphasis" + } + ], + "--color-done-emphasis": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-done-emphasis" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "boxShadow" + ], + "replacement": "--borderColor-done-emphasis" + }, + { + "props": ["color", "fill", "caretColor", "stroke"], + "replacement": "--fgColor-done" + } + ], + "--color-done-muted": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "boxShadow" + ], + "replacement": "--borderColor-done-muted" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-done-muted" + } + ], + "--color-done-subtle": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-done-muted" + } + ], + "--color-sponsors-fg": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--fgColor-sponsors" + }, + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-sponsors-emphasis" + } + ], + "--color-sponsors-emphasis": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-sponsors-emphasis" + }, + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "boxShadow" + ], + "replacement": "--borderColor-sponsors-emphasis" + }, + { + "props": ["color"], + "replacement": "--fgColor-sponsors" + } + ], + "--color-sponsors-muted": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + + "boxShadow" + ], + "replacement": "--borderColor-sponsors-muted" + } + ], + "--color-sponsors-subtle": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--bgColor-sponsors-muted" + } + ], + "--color-primer-fg-disabled": [ + { + "props": ["color", "fill", "caretColor"], + "replacement": "--fgColor-disabled" + } + ], + "--color-primer-canvas-backdrop": [ + { + "props": ["backgroundColor", "bg"], + "replacement": "--overlay-backdrop-bgColor" + } + ], + "--color-primer-border-active": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--underlineNav-borderColor-active" + } + ], + "--color-primer-border-contrast": [ + { + "props": [ + "border", + "borderColor", + "borderTopColor", + "borderRightColor", + "borderBottomColor", + "borderLeftColor", + "boxShadow", + "backgroundColor", + "bg" + ], + "replacement": "--borderColor-muted" + } + ], + "--color-avatar-child-shadow": [ + { + "props": ["boxShadow"], + "replacement": "--avatar-shadow" + } + ], + "--color-btn-text": [ + { + "props": ["color"], + "replacement": "--button-default-fgColor-rest" + } + ], + "--color-btn-shadow": [ + { + "props": ["boxShadow"], + "replacement": "--button-default-shadow-resting" + } + ], + "--color-btn-inset-shadow": [ + { + "props": ["boxShadow"], + "replacement": "--button-default-shadow-inset" + } + ], + "--color-btn-primary-shadow": [ + { + "props": ["boxShadow"], + "replacement": "--shadow-resting-small" + } + ], + "--color-btn-primary-inset-shadow": [ + { + "props": ["boxShadow"], + "replacement": "--shadow-highlight" + } + ], + "--color-btn-primary-selected-shadow": [ + { + "props": ["boxShadow"], + "replacement": "--button-primary-shadow-selected" + } + ], + "--color-btn-outline-hover-shadow": [ + { + "props": ["boxShadow"], + "replacement": "--shadow-resting-small" + } + ], + "--color-btn-outline-hover-inset-shadow": [ + { + "props": ["boxShadow"], + "replacement": "--shadow-highlight" + } + ], + "--color-btn-outline-selected-shadow": [ + { + "props": ["boxShadow"], + "replacement": "--button-outline-shadow-selected" + } + ], + "--color-btn-danger-hover-shadow": [ + { + "props": ["boxShadow"], + "replacement": "--shadow-resting-small" + } + ], + "--color-btn-danger-hover-inset-shadow": [ + { + "props": ["boxShadow"], + "replacement": "--shadow-highlight" + } + ], + "--color-btn-danger-selected-shadow": [ + { + "props": ["boxShadow"], + "replacement": "--button-danger-shadow-selected" + } + ], + "--color-overlay-shadow": [ + { + "props": ["boxShadow"], + "replacement": "--shadow-floating-small" + } + ], + "--color-primer-shadow-highlight": [ + { + "props": ["boxShadow"], + "replacement": "--shadow-highlight" + } + ], + "--color-primer-shadow-inset": [ + { + "props": ["boxShadow"], + "replacement": "--shadow-inset" + } + ], + "--color-shadow-small": [ + { + "props": ["boxShadow"], + "replacement": "--shadow-resting-small" + } + ], + "--color-shadow-medium": [ + { + "props": ["boxShadow"], + "replacement": "--shadow-resting-medium" + } + ], + "--color-shadow-large": [ + { + "props": ["boxShadow"], + "replacement": "--shadow-floating-large" + } + ], + "--color-shadow-extra-large": [ + { + "props": ["boxShadow"], + "replacement": "--shadow-floating-xlarge" + } + ], + "--color-btn-danger-disabled-counter-fg": [ + { + "props": ["color"], + "replacement": "--buttonCounter-danger-fgColor-disabled" + } + ], + "--color-btn-danger-hover-counter-fg": [ + { + "props": ["color"], + "replacement": "--buttonCounter-danger-fgColor-hover" + } + ], + "--color-btn-danger-counter-fg": [ + { + "props": ["color"], + "replacement": "--buttonCounter-danger-fgColor-rest" + } + ], + "--color-btn-outline-disabled-counter-fg": [ + { + "props": ["color"], + "replacement": "--buttonCounter-outline-fgColor-disabled" + } + ], + "--color-btn-outline-hover-counter-fg": [ + { + "props": ["color"], + "replacement": "--buttonCounter-outline-fgColor-hover" + } + ], + "--color-btn-outline-counter-fg": [ + { + "props": ["color"], + "replacement": "--buttonCounter-outline-fgColor-rest" + } + ] +} From 4eb42d8dcf236987d0994bc807e34b2f5cbe297c Mon Sep 17 00:00:00 2001 From: langermank <18661030+langermank@users.noreply.github.com> Date: Wed, 27 Sep 2023 12:27:06 -0700 Subject: [PATCH 11/18] fix tests Co-authored-by: Josh Black --- ...ars.test.js => new-color-css-vars.test.js} | 82 +++++-------------- ...olor-css-vars.js => new-color-css-vars.js} | 60 ++++++++++---- 2 files changed, 64 insertions(+), 78 deletions(-) rename src/rules/__tests__/{no-color-css-vars.test.js => new-color-css-vars.test.js} (63%) rename src/rules/{no-color-css-vars.js => new-color-css-vars.js} (71%) diff --git a/src/rules/__tests__/no-color-css-vars.test.js b/src/rules/__tests__/new-color-css-vars.test.js similarity index 63% rename from src/rules/__tests__/no-color-css-vars.test.js rename to src/rules/__tests__/new-color-css-vars.test.js index 2bf1aeb3..9a1c2d75 100644 --- a/src/rules/__tests__/no-color-css-vars.test.js +++ b/src/rules/__tests__/new-color-css-vars.test.js @@ -1,4 +1,4 @@ -const rule = require('../no-color-css-vars') +const rule = require('../new-color-css-vars') const {RuleTester} = require('eslint') const ruleTester = new RuleTester({ @@ -124,68 +124,24 @@ ruleTester.run('no-color-css-vars', rule, { message: 'Replace var(--color-border-default) with var(--borderColor-default, var(--color-border-default))' } ] + }, + { + name: 'variable in styled.component', + code: ` + import {sx, SxProp} from '@primer/react' + export const HighlightToken = styled.span\` + color: var(--color-accent-emphasis); + \${sx} + \` + const ClickableTokenSpan = styled(HighlightToken)\` + &:hover, &:focus { background-color: accent.muted;} + \` + `, + errors: [ + { + message: 'Replace var(--color-accent-emphasis) with var(--fgColor-accent, var(--color-accent-emphasis))' + } + ] } - // broken tests start below - // { - // name: 'variable in styled.component', - // code: ` - // import {sx, SxProp} from '@primer/react' - // export const HighlightToken = styled.span\` - // color: var(--color-accent-emphasis); - // \${sx} - // \` - // const ClickableTokenSpan = styled(HighlightToken)\` - // &:hover, &:focus { background-color: accent.muted;} - // \` - // `, - // output: ` - // import {sx, SxProp} from '@primer/react' - // export const HighlightToken = styled.span\` - // color: var(--bgColor-accent-emphasis, var(--color-accent-emphasis)); - // \${sx} - // \` - // const ClickableTokenSpan = styled(HighlightToken)\` - // &:hover, &:focus { background-color: accent.muted;} - // \` - // `, - // errors: [ - // { - // message: - // 'Replace var(--color-accent-emphasis) with var(--bgColor-accent-emphasis, var(--color-accent-emphasis))' - // } - // ] - // } - // { - // name: 'MemberExpression in sx: not handled', - // code: ` - // const colors = { muted: 'var(--color-fg-muted)' } - // export const Fixture = - // `, - // output: ` - // const colors = { muted: 'var(--fgColor-muted, var(--color-fg-muted))' } - // export const Fixture = - // `, - // errors: [ - // { - // message: 'Replace var(--color-fg-muted) with var(--fgColor-muted, var(--color-fg-muted))' - // } - // ] - // } - // { - // name: 'CallExpression in sx: not handled', - // code: ` - // const getColors = () => 'var(--color-fg-muted)' - // export const Fixture = - // `, - // output: ` - // const getColors = () => 'var(--fgColor-muted, var(--color-fg-muted))' - // export const Fixture = - // `, - // errors: [ - // { - // message: 'Replace var(--color-fg-muted) with var(--fgColor-muted, var(--color-fg-muted))' - // } - // ] - // } ] }) diff --git a/src/rules/no-color-css-vars.js b/src/rules/new-color-css-vars.js similarity index 71% rename from src/rules/no-color-css-vars.js rename to src/rules/new-color-css-vars.js index 01399710..61f6e4ad 100644 --- a/src/rules/no-color-css-vars.js +++ b/src/rules/new-color-css-vars.js @@ -70,6 +70,51 @@ module.exports = { ) { checkForVariables(node.value, node.value.value) } + }, + TaggedTemplateExpression(node) { + if (node.tag.type !== 'MemberExpression') { + return + } + + if (node.tag.object.name !== 'styled') { + return + } + + const DECLARATION_REGEX = /(.+): (var\(--color-.+\));/ + + // const StyledComponent = styled.div` + // color: var(--color-fg-example); + // background: var(--color-bg-example); + // `; + for (const templateElement of node.quasi.quasis) { + const rawValue = templateElement.value.raw + const match = rawValue.match(DECLARATION_REGEX) + if (!match) { + continue + } + + const property = match[1].trim() + const value = match[2].trim() + + for (const [cssVar, replacements] of Object.entries(cssVars)) { + const regex = new RegExp(`var\\(${cssVar}\\)`, 'g') + + for (const {props, replacement} of replacements) { + if (!props.includes(property)) { + continue + } + + if (!regex.test(value)) { + continue + } + + context.report({ + node, + message: `Replace var(${cssVar}) with var(${replacement}, var(${cssVar}))` + }) + } + } + } } } @@ -77,21 +122,6 @@ module.exports = { // performance optimisation: exit early if (!rawText.includes('var')) return - // Object.keys(cssVars).forEach(cssVar => { - // if (rawText.includes(`var(${cssVar}`)) { - // const fixedString = rawText.replace(`var(${cssVar})`, cssVars[cssVar]) - - // context.report({ - // node, - // message: `Replace var(${cssVar}) with ${cssVars[cssVar]}`, - // fix: function(fixer) { - // return fixer.replaceText(node, node.type === 'Literal' ? `"${fixedString}"` : fixedString) - // } - // }) - // } - // }) - - console.log('Rule is being executed') Object.keys(cssVars).forEach(cssVar => { if (Array.isArray(cssVars[cssVar])) { cssVars[cssVar].forEach(cssVarObject => { From 1e4ade58416eb7b1321a374f7b6465e7a52da4e6 Mon Sep 17 00:00:00 2001 From: langermank <18661030+langermank@users.noreply.github.com> Date: Wed, 27 Sep 2023 12:29:07 -0700 Subject: [PATCH 12/18] remove unused file --- src/utils/css-var-map.json | 75 -------------------------------------- 1 file changed, 75 deletions(-) delete mode 100644 src/utils/css-var-map.json diff --git a/src/utils/css-var-map.json b/src/utils/css-var-map.json deleted file mode 100644 index 0aa1b359..00000000 --- a/src/utils/css-var-map.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "--color-canvas-default-transparent": "canvasDefaultTransparent", - "--color-control-border-color-emphasis": "control.borderColor.emphasis", - "--color-action-list-item-inline-divider": "actionListItem.inlineDivider", - "--color-action-list-item-default-hover-bg": "actionListItem.default.hoverBg", - "--color-action-list-item-default-hover-border": "actionListItem.default.hoverBorder", - "--color-action-list-item-default-active-bg": "actionListItem.default.activeBg", - "--color-action-list-item-default-active-border": "actionListItem.default.activeBorder", - "--color-action-list-item-default-selected-bg": "actionListItem.default.selectedBg", - "--color-action-list-item-danger-hover-bg": "actionListItem.danger.hoverBg", - "--color-action-list-item-danger-active-bg": "actionListItem.danger.activeBg", - "--color-action-list-item-danger-hover-text": "actionListItem.danger.hoverText", - "--color-fg-default": "fg.default", - "--color-fg-muted": "fg.muted", - "--color-fg-subtle": "fg.subtle", - "--color-fg-on-emphasis": "fg.onEmphasis", - "--color-canvas-default": "canvas.default", - "--color-canvas-overlay": "canvas.overlay", - "--color-canvas-inset": "canvas.inset", - "--color-canvas-subtle": "canvas.subtle", - "--color-border-default": "border.default", - "--color-border-muted": "border.muted", - "--color-border-subtle": "border.subtle", - "--color-shadow-small": "shadow.small", - "--color-shadow-medium": "shadow.medium", - "--color-shadow-large": "shadow.large", - "--color-shadow-extra-large": "shadow.extraLarge", - "--color-neutral-emphasis-plus": "neutral.emphasisPlus", - "--color-neutral-emphasis": "neutral.emphasis", - "--color-neutral-muted": "neutral.muted", - "--color-neutral-subtle": "neutral.subtle", - "--color-accent-fg": "accent.fg", - "--color-accent-emphasis": "accent.emphasis", - "--color-accent-muted": "accent.muted", - "--color-accent-subtle": "accent.subtle", - "--color-success-fg": "success.fg", - "--color-success-emphasis": "success.emphasis", - "--color-success-muted": "success.muted", - "--color-success-subtle": "success.subtle", - "--color-attention-fg": "attention.fg", - "--color-attention-emphasis": "attention.emphasis", - "--color-attention-muted": "attention.muted", - "--color-attention-subtle": "attention.subtle", - "--color-severe-fg": "severe.fg", - "--color-severe-emphasis": "severe.emphasis", - "--color-severe-muted": "severe.muted", - "--color-severe-subtle": "severe.subtle", - "--color-danger-fg": "danger.fg", - "--color-danger-emphasis": "danger.emphasis", - "--color-danger-muted": "danger.muted", - "--color-danger-subtle": "danger.subtle", - "--color-open-fg": "open.fg", - "--color-open-emphasis": "open.emphasis", - "--color-open-muted": "open.muted", - "--color-open-subtle": "open.subtle", - "--color-closed-fg": "closed.fg", - "--color-closed-emphasis": "closed.emphasis", - "--color-closed-muted": "closed.muted", - "--color-closed-subtle": "closed.subtle", - "--color-done-fg": "done.fg", - "--color-done-emphasis": "done.emphasis", - "--color-done-muted": "done.muted", - "--color-done-subtle": "done.subtle", - "--color-sponsors-fg": "sponsors.fg", - "--color-sponsors-emphasis": "sponsors.emphasis", - "--color-sponsors-muted": "sponsors.muted", - "--color-sponsors-subtle": "sponsors.subtle", - "--color-primer-fg-disabled": "actionListItem", - "--color-primer-canvas-backdrop": "primer.canvas.backdrop", - "--color-primer-canvas-sticky": "primer.canvas.sticky", - "--color-primer-border-active": "primer.border.active", - "--color-primer-border-contrast": "primer.border.contrast", - "--color-primer-shadow-highlight": "primer.shadow.highlight", - "--color-primer-shadow-inset": "primer.shadow.inset" -} From 361f8520bca78ea3ba616ed24cf1986547b87d8a Mon Sep 17 00:00:00 2001 From: langermank <18661030+langermank@users.noreply.github.com> Date: Wed, 27 Sep 2023 16:05:10 -0700 Subject: [PATCH 13/18] import rule --- src/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index b757c851..dc982df2 100644 --- a/src/index.js +++ b/src/index.js @@ -3,7 +3,8 @@ module.exports = { 'direct-slot-children': require('./rules/direct-slot-children'), 'no-deprecated-colors': require('./rules/no-deprecated-colors'), 'no-system-props': require('./rules/no-system-props'), - 'a11y-tooltip-interactive-trigger': require('./rules/a11y-tooltip-interactive-trigger') + 'a11y-tooltip-interactive-trigger': require('./rules/a11y-tooltip-interactive-trigger'), + 'new-color-css-vars': require('./rules/new-color-css-vars') }, configs: { recommended: require('./configs/recommended') From bf08eea57302b6a5a9e6eba9c17e407533156bc8 Mon Sep 17 00:00:00 2001 From: Armagan Ersoz Date: Thu, 28 Sep 2023 09:19:41 +1000 Subject: [PATCH 14/18] export rules in the recommanded config --- src/configs/recommended.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/configs/recommended.js b/src/configs/recommended.js index b1f706d5..9c761c35 100644 --- a/src/configs/recommended.js +++ b/src/configs/recommended.js @@ -11,7 +11,8 @@ module.exports = { 'primer-react/direct-slot-children': 'error', 'primer-react/no-deprecated-colors': 'warn', 'primer-react/no-system-props': 'warn', - 'primer-react/a11y-tooltip-interactive-trigger': 'error' + 'primer-react/a11y-tooltip-interactive-trigger': 'error', + 'primer-react/new-color-css-vars': 'error' }, settings: { github: { From eb2ad6719697bf09a195dc30c372646a029b1bcb Mon Sep 17 00:00:00 2001 From: langermank <18661030+langermank@users.noreply.github.com> Date: Thu, 28 Sep 2023 13:15:29 -0700 Subject: [PATCH 15/18] test to fix autofix --- src/rules/new-color-css-vars.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/rules/new-color-css-vars.js b/src/rules/new-color-css-vars.js index 61f6e4ad..46cbf4b5 100644 --- a/src/rules/new-color-css-vars.js +++ b/src/rules/new-color-css-vars.js @@ -125,17 +125,22 @@ module.exports = { Object.keys(cssVars).forEach(cssVar => { if (Array.isArray(cssVars[cssVar])) { cssVars[cssVar].forEach(cssVarObject => { - const regex = new RegExp(`var\\(${cssVar}\\)`, 'g') - if (cssVarObject.props.some(prop => rawText.includes(prop)) && regex.test(rawText)) { - const fixedString = rawText.replace(regex, `var(${cssVarObject.replacement}, var(${cssVar}))`) - context.report({ - node, - message: `Replace var(${cssVar}) with var(${cssVarObject.replacement}, var(${cssVar}))`, - fix: function(fixer) { - return fixer.replaceText(node, node.type === 'Literal' ? `"${fixedString}"` : fixedString) + cssVarObject.props.forEach(prop => { + const regex = new RegExp(`var\\(${cssVar}\\)`, 'g') + if (rawText.includes(prop) && regex.test(rawText)) { + const fixedString = rawText.replace(regex, `var(${cssVarObject.replacement}, var(${cssVar}))`) + if (!rawText.includes(fixedString)) { + // Check if the autofix has already been applied + context.report({ + node, + message: `Replace var(${cssVar}) with var(${cssVarObject.replacement}, var(${cssVar}))`, + fix: function(fixer) { + return fixer.replaceText(node, node.type === 'Literal' ? `"${fixedString}"` : fixedString) + } + }) } - }) - } + } + }) }) } }) From a089bcd35ca6a397129d68a47fc9e9bfc3f45853 Mon Sep 17 00:00:00 2001 From: langermank <18661030+langermank@users.noreply.github.com> Date: Thu, 28 Sep 2023 13:21:13 -0700 Subject: [PATCH 16/18] try to fix autofix again --- src/rules/new-color-css-vars.js | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/rules/new-color-css-vars.js b/src/rules/new-color-css-vars.js index 46cbf4b5..cb70b89e 100644 --- a/src/rules/new-color-css-vars.js +++ b/src/rules/new-color-css-vars.js @@ -125,22 +125,19 @@ module.exports = { Object.keys(cssVars).forEach(cssVar => { if (Array.isArray(cssVars[cssVar])) { cssVars[cssVar].forEach(cssVarObject => { - cssVarObject.props.forEach(prop => { - const regex = new RegExp(`var\\(${cssVar}\\)`, 'g') - if (rawText.includes(prop) && regex.test(rawText)) { - const fixedString = rawText.replace(regex, `var(${cssVarObject.replacement}, var(${cssVar}))`) - if (!rawText.includes(fixedString)) { - // Check if the autofix has already been applied - context.report({ - node, - message: `Replace var(${cssVar}) with var(${cssVarObject.replacement}, var(${cssVar}))`, - fix: function(fixer) { - return fixer.replaceText(node, node.type === 'Literal' ? `"${fixedString}"` : fixedString) - } - }) - } + const regex = new RegExp(`var\\(${cssVar}\\)`, 'g') + if (cssVarObject.props.some(prop => rawText.includes(prop)) && regex.test(rawText)) { + const fixedString = rawText.replace(regex, `var(${cssVarObject.replacement}, var(${cssVar}))`) + if (!rawText.includes(fixedString)) { + context.report({ + node, + message: `Replace var(${cssVar}) with var(${cssVarObject.replacement}, var(${cssVar}))`, + fix: function(fixer) { + return fixer.replaceText(node, node.type === 'Literal' ? `"${fixedString}"` : fixedString) + } + }) } - }) + } }) } }) From f9eb90f625f67dc103d041de5a55df59202ac1da Mon Sep 17 00:00:00 2001 From: langermank <18661030+langermank@users.noreply.github.com> Date: Mon, 2 Oct 2023 10:03:17 -0700 Subject: [PATCH 17/18] only support sx prop in favor of stylelint --- .../__tests__/new-color-css-vars.test.js | 21 ++------ src/rules/new-color-css-vars.js | 54 +++---------------- 2 files changed, 10 insertions(+), 65 deletions(-) diff --git a/src/rules/__tests__/new-color-css-vars.test.js b/src/rules/__tests__/new-color-css-vars.test.js index 9a1c2d75..f95501dc 100644 --- a/src/rules/__tests__/new-color-css-vars.test.js +++ b/src/rules/__tests__/new-color-css-vars.test.js @@ -24,6 +24,9 @@ ruleTester.run('no-color-css-vars', rule, { }, { code: `
` + }, + { + code: `` } ], invalid: [ @@ -124,24 +127,6 @@ ruleTester.run('no-color-css-vars', rule, { message: 'Replace var(--color-border-default) with var(--borderColor-default, var(--color-border-default))' } ] - }, - { - name: 'variable in styled.component', - code: ` - import {sx, SxProp} from '@primer/react' - export const HighlightToken = styled.span\` - color: var(--color-accent-emphasis); - \${sx} - \` - const ClickableTokenSpan = styled(HighlightToken)\` - &:hover, &:focus { background-color: accent.muted;} - \` - `, - errors: [ - { - message: 'Replace var(--color-accent-emphasis) with var(--fgColor-accent, var(--color-accent-emphasis))' - } - ] } ] }) diff --git a/src/rules/new-color-css-vars.js b/src/rules/new-color-css-vars.js index cb70b89e..829db4a6 100644 --- a/src/rules/new-color-css-vars.js +++ b/src/rules/new-color-css-vars.js @@ -6,7 +6,7 @@ module.exports = { hasSuggestions: true, fixable: 'code', docs: { - description: 'Disallow the use of CSS color variables in React' + description: 'Upgrade legacy CSS variables to Primitives v8 in sx prop' }, schema: [ { @@ -65,56 +65,12 @@ module.exports = { } } else if ( styledSystemProps.includes(node.name.name) && + node.value && node.value.type === 'Literal' && typeof node.value.value === 'string' ) { checkForVariables(node.value, node.value.value) } - }, - TaggedTemplateExpression(node) { - if (node.tag.type !== 'MemberExpression') { - return - } - - if (node.tag.object.name !== 'styled') { - return - } - - const DECLARATION_REGEX = /(.+): (var\(--color-.+\));/ - - // const StyledComponent = styled.div` - // color: var(--color-fg-example); - // background: var(--color-bg-example); - // `; - for (const templateElement of node.quasi.quasis) { - const rawValue = templateElement.value.raw - const match = rawValue.match(DECLARATION_REGEX) - if (!match) { - continue - } - - const property = match[1].trim() - const value = match[2].trim() - - for (const [cssVar, replacements] of Object.entries(cssVars)) { - const regex = new RegExp(`var\\(${cssVar}\\)`, 'g') - - for (const {props, replacement} of replacements) { - if (!props.includes(property)) { - continue - } - - if (!regex.test(value)) { - continue - } - - context.report({ - node, - message: `Replace var(${cssVar}) with var(${replacement}, var(${cssVar}))` - }) - } - } - } } } @@ -126,7 +82,11 @@ module.exports = { if (Array.isArray(cssVars[cssVar])) { cssVars[cssVar].forEach(cssVarObject => { const regex = new RegExp(`var\\(${cssVar}\\)`, 'g') - if (cssVarObject.props.some(prop => rawText.includes(prop)) && regex.test(rawText)) { + if ( + cssVarObject.props.some(prop => rawText.includes(prop)) && + regex.test(rawText) && + !rawText.includes(cssVarObject.replacement) + ) { const fixedString = rawText.replace(regex, `var(${cssVarObject.replacement}, var(${cssVar}))`) if (!rawText.includes(fixedString)) { context.report({ From 821ef4d2a1b87f2418cb9c48bed37b793361b282 Mon Sep 17 00:00:00 2001 From: Katie Langerman <18661030+langermank@users.noreply.github.com> Date: Mon, 2 Oct 2023 10:08:23 -0700 Subject: [PATCH 18/18] Create early-ads-clap.md --- .changeset/early-ads-clap.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/early-ads-clap.md diff --git a/.changeset/early-ads-clap.md b/.changeset/early-ads-clap.md new file mode 100644 index 00000000..e48761b9 --- /dev/null +++ b/.changeset/early-ads-clap.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-primer-react": patch +--- + +New rule: `new-color-css-vars` to find/replace legacy CSS color vars in sx prop