From 3c80fef152f5baa2ecc47a50dce051c1c453a52f Mon Sep 17 00:00:00 2001 From: Ollie Curtis <8831547+olliecurtis@users.noreply.github.com> Date: Thu, 26 Oct 2023 15:38:15 +0100 Subject: [PATCH] [ARGG-799]: Migrates from bpk-tokens to bpk-foundations-web (#85) * [ARGG-799]: Migrates from bpk-tokens to bpk-foundations-web * Remove console log --- README.md | 3 +- package-lock.json | 89 +++-- package.json | 2 +- src/rules/use-components/use-components.js | 12 +- .../use-components/use-components.test.js | 111 ------ .../use-components/use-native-components.js | 129 ------- src/rules/use-tokens/use-tokens.js | 126 ++----- src/rules/use-tokens/use-tokens.test.js | 356 +++++------------- 8 files changed, 180 insertions(+), 648 deletions(-) delete mode 100644 src/rules/use-components/use-native-components.js diff --git a/README.md b/README.md index 7bca62c..facdc7e 100644 --- a/README.md +++ b/README.md @@ -60,8 +60,7 @@ Available for colours and length values. Will prevent the use of a hardcoded col "autoImport": true, "platform": "web", "tokensPackage": { - "web": "bpk-tokens/tokens/base.es6", - "native": "bpk-tokens/tokens/base.react.native", + "web": "@skyscanner/bpk-foundations-web/tokens/base.es6", }, }] } diff --git a/package-lock.json b/package-lock.json index b6cae9e..76d1c69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "5.0.0", "license": "Apache-2.0", "dependencies": { - "bpk-tokens": "^36.0.0", + "@skyscanner/bpk-foundations-web": "^17.3.0", "lodash": "^4.17.21", "tinycolor2": "^1.6.0" }, @@ -619,6 +619,23 @@ "node": ">= 8" } }, + "node_modules/@skyscanner/bpk-foundations-common": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@skyscanner/bpk-foundations-common/-/bpk-foundations-common-6.5.0.tgz", + "integrity": "sha512-nOk8DspPlbcAtswcQFzwaS8eg55ObJIY/pHl6ZCS3JaCZliTdEp4hJFl1Bb841z7TyMx+JwBOjIwvAN3x7lquw==", + "dependencies": { + "color": "^3.0.0" + } + }, + "node_modules/@skyscanner/bpk-foundations-web": { + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/@skyscanner/bpk-foundations-web/-/bpk-foundations-web-17.4.0.tgz", + "integrity": "sha512-JA8SE0Bzw4XnPx7PC5qvOiy49gswg7nSA3T6FfjR4AGXNME9fbEI6Ii5JM/IjcU2aJySt0iJQiN26/HsowZguw==", + "dependencies": { + "@skyscanner/bpk-foundations-common": "^6.5.0", + "color": "^3.0.0" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -720,15 +737,6 @@ "node": ">=8" } }, - "node_modules/bpk-tokens": { - "version": "36.0.0", - "resolved": "https://registry.npmjs.org/bpk-tokens/-/bpk-tokens-36.0.0.tgz", - "integrity": "sha512-gNir+QiHb4zYLrYMUH6xoYl34ZvRevigsCorHC3OdwhERV7qkROrf5SmeeWXuoXjFUv03Bz7tWYmNfW1FePaOQ==", - "deprecated": "This package has now been deprecated and no longer supported as we move to foundations. Please install the platform specific token package as per the advice from https://github.com/Skyscanner/backpack-foundations\\#bpk-androidiosreact-nativeweb", - "dependencies": { - "color": "^3.0.0" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -883,12 +891,12 @@ } }, "node_modules/color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz", - "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", "dependencies": { - "color-convert": "^1.9.1", - "color-string": "^1.5.4" + "color-convert": "^1.9.3", + "color-string": "^1.6.0" } }, "node_modules/color-convert": { @@ -905,9 +913,9 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "node_modules/color-string": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.4.tgz", - "integrity": "sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -2438,7 +2446,7 @@ "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "dependencies": { "is-arrayish": "^0.3.1" } @@ -3157,6 +3165,23 @@ "fastq": "^1.6.0" } }, + "@skyscanner/bpk-foundations-common": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@skyscanner/bpk-foundations-common/-/bpk-foundations-common-6.5.0.tgz", + "integrity": "sha512-nOk8DspPlbcAtswcQFzwaS8eg55ObJIY/pHl6ZCS3JaCZliTdEp4hJFl1Bb841z7TyMx+JwBOjIwvAN3x7lquw==", + "requires": { + "color": "^3.0.0" + } + }, + "@skyscanner/bpk-foundations-web": { + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/@skyscanner/bpk-foundations-web/-/bpk-foundations-web-17.4.0.tgz", + "integrity": "sha512-JA8SE0Bzw4XnPx7PC5qvOiy49gswg7nSA3T6FfjR4AGXNME9fbEI6Ii5JM/IjcU2aJySt0iJQiN26/HsowZguw==", + "requires": { + "@skyscanner/bpk-foundations-common": "^6.5.0", + "color": "^3.0.0" + } + }, "@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -3231,14 +3256,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "bpk-tokens": { - "version": "36.0.0", - "resolved": "https://registry.npmjs.org/bpk-tokens/-/bpk-tokens-36.0.0.tgz", - "integrity": "sha512-gNir+QiHb4zYLrYMUH6xoYl34ZvRevigsCorHC3OdwhERV7qkROrf5SmeeWXuoXjFUv03Bz7tWYmNfW1FePaOQ==", - "requires": { - "color": "^3.0.0" - } - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3333,12 +3350,12 @@ } }, "color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz", - "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.4" + "color-convert": "^1.9.3", + "color-string": "^1.6.0" } }, "color-convert": { @@ -3355,9 +3372,9 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.4.tgz", - "integrity": "sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", "requires": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -4457,7 +4474,7 @@ "simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "requires": { "is-arrayish": "^0.3.1" } diff --git a/package.json b/package.json index cc361a6..66ed23e 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ }, "license": "Apache-2.0", "dependencies": { - "bpk-tokens": "^36.0.0", + "@skyscanner/bpk-foundations-web": "^17.3.0", "lodash": "^4.17.21", "tinycolor2": "^1.6.0" }, diff --git a/src/rules/use-components/use-components.js b/src/rules/use-components/use-components.js index 5616643..3c8e169 100644 --- a/src/rules/use-components/use-components.js +++ b/src/rules/use-components/use-components.js @@ -17,19 +17,9 @@ const merge = require('lodash/merge'); const useWebComponents = require('./use-web-components'); -const useNativeComponents = require('./use-native-components'); - -const BASE_CONFIG = { - autoImport: true, - platform: 'web', -}; const createConfigForPlatform = (report, options) => { - const config = merge({}, BASE_CONFIG, options[0]); - if (config.platform === 'web') { - return useWebComponents(report, options); - } - return useNativeComponents(report, options); + return useWebComponents(report, options); }; module.exports = { diff --git a/src/rules/use-components/use-components.test.js b/src/rules/use-components/use-components.test.js index fb335d3..57310b6 100644 --- a/src/rules/use-components/use-components.test.js +++ b/src/rules/use-components/use-components.test.js @@ -20,8 +20,6 @@ const { RuleTester } = require('eslint'); const useComponents = require('./use-components'); -const BPK_PATH = 'backpack-react-native/'; - const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2015, @@ -30,115 +28,6 @@ const ruleTester = new RuleTester({ }, }); -/* platform: 'native' tests. */ -[ - ['ActivityIndicator', 'BpkSpinner', 'bpk-component-spinner'], - ['Alert', 'BpkAlert', 'bpk-component-alert'], - ['Button', 'BpkButton', 'bpk-component-button'], - ['FlatList', 'BpkFlatList', 'bpk-component-flat-list'], - ['Image', 'BpkImage', 'bpk-component-image'], - ['Picker', 'BpkPicker', 'bpk-component-picker'], - ['SectionList', 'BpkSectionList', 'bpk-component-section-list'], - ['Switch', 'BpkSwitch', 'bpk-component-switch'], - ['Text', 'BpkText', 'bpk-component-text'], - ['TextInput', 'BpkTextInput', 'bpk-component-text-input'], - [ - 'TouchableHighlight', - 'BpkTouchableOverlay', - 'bpk-component-touchable-overlay', - ], - [ - 'TouchableNativeFeedback', - 'BpkTouchableNativeFeedback', - 'bpk-component-touchable-native-feedback', - ], -].forEach(([Component, Substitute, pkg]) => { - const pkgPath = BPK_PATH + pkg; - - ruleTester.run(`use-components (native) - ${Component}`, useComponents, { - valid: [ - `<${Substitute}>I'm allowed`, - `
I'm allowed
`, - `React.createElement(SomeElement, null)`, - `React.createElement("div", null)`, - ], - invalid: [ - { - options: [{ platform: 'native' }], - code: `React.createElement(${Component}, null, "I'm not allowed")`, - output: ` -import ${Substitute} from '${pkgPath}'; -React.createElement(${Substitute}, null, "I'm not allowed")`, - errors: [ - { - message: `Use the following Backpack component instead: ${Substitute}`, - }, - ], - }, - { - options: [{ platform: 'native' }], - code: `create(${Component}, null, "I'm not allowed")`, - output: ` -import ${Substitute} from '${pkgPath}'; -create(${Substitute}, null, "I'm not allowed")`, - errors: [ - { - message: `Use the following Backpack component instead: ${Substitute}`, - }, - ], - }, - { - options: [{ platform: 'native' }], - code: `<${Component}>I'm not allowed`, - output: ` -import ${Substitute} from '${pkgPath}'; -<${Substitute}>I'm not allowed`, - errors: [ - { - message: `Use the following Backpack component instead: ${Substitute}`, - }, - ], - }, - { - options: [{ platform: 'native' }], - code: `<${Component} children="I'm not allowed" />`, - output: ` -import ${Substitute} from '${pkgPath}'; -<${Substitute} children="I'm not allowed" />`, - errors: [ - { - message: `Use the following Backpack component instead: ${Substitute}`, - }, - ], - }, - { - options: [{ autoImport: false, platform: 'native' }], - code: `<${Component} children="I'm not allowed" />`, - output: `<${Substitute} children="I'm not allowed" />`, - errors: [ - { - message: `Use the following Backpack component instead: ${Substitute}`, - }, - ], - }, - { - options: [{ platform: 'native' }], - code: ` -import ${Substitute} from '${pkgPath}'; -<${Component} children="I'm not allowed" />`, - output: ` -import ${Substitute} from '${pkgPath}'; -<${Substitute} children="I'm not allowed" />`, - errors: [ - { - message: `Use the following Backpack component instead: ${Substitute}`, - }, - ], - }, - ], - }); -}); - /* platform: 'web' tests */ const createImportStatement = (Substitute, useDefaultImport, pkgPath) => `import ${ diff --git a/src/rules/use-components/use-native-components.js b/src/rules/use-components/use-native-components.js deleted file mode 100644 index 57684ac..0000000 --- a/src/rules/use-components/use-native-components.js +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Backpack - Skyscanner's Design System - * - * Copyright 2018-present Skyscanner Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -const merge = require('lodash/merge'); - -const { addImport, getImportDefinition } = require('../../auto-import'); - -const BPK_PATH = 'backpack-react-native/'; - -const BPK_SUBSTITUTES = { - ActivityIndicator: 'BpkSpinner', - Alert: 'BpkAlert', - Button: 'BpkButton', - FlatList: 'BpkFlatList', - Image: 'BpkImage', - Picker: 'BpkPicker', - SectionList: 'BpkSectionList', - Switch: 'BpkSwitch', - Text: 'BpkText', - TextInput: 'BpkTextInput', - TouchableHighlight: 'BpkTouchableOverlay', - TouchableNativeFeedback: 'BpkTouchableNativeFeedback', -}; - -const PACKAGES = { - BpkSpinner: 'bpk-component-spinner', - BpkAlert: 'bpk-component-alert', - BpkButton: 'bpk-component-button', - BpkFlatList: 'bpk-component-flat-list', - BpkImage: 'bpk-component-image', - BpkPicker: 'bpk-component-picker', - BpkSectionList: 'bpk-component-section-list', - BpkSwitch: 'bpk-component-switch', - BpkText: 'bpk-component-text', - BpkTextInput: 'bpk-component-text-input', - BpkTouchableOverlay: 'bpk-component-touchable-overlay', - BpkTouchableNativeFeedback: 'bpk-component-touchable-native-feedback', -}; - -const BASE_CONFIG = { - autoImport: true, -}; - -const ruleMessage = bpkComponent => - `Use the following Backpack component instead: ${bpkComponent}`; - -const fixAndMaybeImport = (fixer, options, node, identifier, fixes) => { - const config = merge({}, BASE_CONFIG, options); - const packageName = BPK_PATH + PACKAGES[identifier]; - - if (!config.autoImport) { - return fixes; - } - - const importDef = getImportDefinition(node, identifier, { - packageName, - style: 'default', - }); - - if (importDef.isImported) { - return fixes; - } - - return [addImport(fixer, importDef)].concat(fixes); -}; - -module.exports = (report, options) => ({ - CallExpression: node => { - const { arguments: args } = node; - - if (args.length >= 1 && args[0].type === 'Identifier') { - const bpkSubstitute = BPK_SUBSTITUTES[args[0].name]; - if (!bpkSubstitute) { - return; - } - - report({ - node: args[0], - message: ruleMessage(bpkSubstitute), - fix: fixer => - fixAndMaybeImport( - fixer, - options[0], - node, - bpkSubstitute, - fixer.replaceTextRange( - [args[0].range[0], args[0].range[1]], - bpkSubstitute, - ), - ), - }); - } - }, - - JSXElement: node => { - const { openingElement, closingElement } = node; - const bpkSubstitute = BPK_SUBSTITUTES[openingElement.name.name]; - if (!bpkSubstitute) { - return; - } - - report({ - node: openingElement, - message: ruleMessage(bpkSubstitute), - fix(fixer) { - const fixIt = toFix => fixer.replaceText(toFix.name, bpkSubstitute); - const fixes = openingElement.selfClosing - ? fixIt(openingElement) - : [fixIt(openingElement), fixIt(closingElement)]; - - return fixAndMaybeImport(fixer, options[0], node, bpkSubstitute, fixes); - }, - }); - }, -}); diff --git a/src/rules/use-tokens/use-tokens.js b/src/rules/use-tokens/use-tokens.js index b1d1f2e..4cbe3b7 100644 --- a/src/rules/use-tokens/use-tokens.js +++ b/src/rules/use-tokens/use-tokens.js @@ -17,24 +17,13 @@ const _ = require('lodash'); const tinycolor = require('tinycolor2'); -const { props: WEB_TOKENS } = require('bpk-tokens/tokens/base.raw.json'); -const { props: IOS_TOKENS } = require('bpk-tokens/tokens/base.raw.ios.json'); const { - props: ANDROID_TOKENS, -} = require('bpk-tokens/tokens/base.raw.android.json'); + props: WEB_TOKENS, +} = require('@skyscanner/bpk-foundations-web/tokens/base.raw.json'); const { addImport, getImportDefinition } = require('../../auto-import'); -const BASE_CONFIG = { - autoImport: true, - platform: 'web', - tokensPackage: { - web: 'bpk-tokens/tokens/base.es6', - native: 'bpk-tokens/tokens/base.react.native', - }, -}; - -const COLOR_WHITELIST = ['transparent', null, undefined]; +const COLOR_ALLOWLIST = ['transparent', null, undefined]; const COLOR_PROPS = ['color', 'backgroundColor']; const RADII_PROPS = [ @@ -59,44 +48,7 @@ const BORDER_PROPS = [ 'borderWidth', ]; -const SPACING_PROPS = [ - 'bottom', - 'end', - 'height', - 'left', - 'margin', - 'marginBottom', - 'marginEnd', - 'marginHorizontal', - 'marginLeft', - 'marginRight', - 'marginStart', - 'marginTop', - 'marginVertical', - 'maxHeight', - 'maxWidth', - 'minHeight', - 'minWidth', - 'padding', - 'paddingBottom', - 'paddingEnd', - 'paddingHorizontal', - 'paddingLeft', - 'paddingRight', - 'paddingStart', - 'paddingTop', - 'paddingVertical', - 'right', - 'start', - 'top', - 'width', -]; - -const TOKENS = _.merge( - _.mapKeys(WEB_TOKENS, (value, key) => `WEB_${key}`), - _.mapKeys(IOS_TOKENS, (value, key) => `IOS_${key}`), - _.mapKeys(ANDROID_TOKENS, (value, key) => `ANDROID_${key}`), -); +const TOKENS = _.merge(_.mapKeys(WEB_TOKENS, (value, key) => `WEB_${key}`)); const tokensByCategory = category => _.chain(TOKENS) @@ -107,56 +59,49 @@ const tokensByCategory = category => })) .value(); -const COLORS = tokensByCategory('colors'); -const SPACING_NAMES = new Set(tokensByCategory('spacings').map(x => x.name)); +const tokensByType = type => + _.chain(TOKENS) + .filter({ type: type }) + .map(({ name, value, deprecated }) => ({ + name: _.camelCase(name), + value, + deprecated, + })) + .value(); + +const COLORS = tokensByType('color').filter(function(el) { + return el.deprecated !== true; +}); + const RADII_NAMES = new Set(tokensByCategory('radii').map(x => x.name)); const BORDER_NAMES = new Set(tokensByCategory('borders').map(x => x.name)); const checkColor = (node, context) => { const { key, value } = node; const isColor = COLOR_PROPS.includes(key.name) && value.type === 'Literal'; - - if (!isColor) { + const allowedColor = COLOR_ALLOWLIST.filter(c => value.value === c).length; + // We check if the colour is in the allowlist, or if it's a valid Backpack token + if (!isColor || allowedColor) { return; } const color = tinycolor(value.value); - const expectedToken = _.find(COLORS, { value: color.toRgbString() }); - - if (expectedToken) { + const matchedTokens = _.filter(COLORS, { value: color.toRgbString() }); + if (matchedTokens.length > 1) { context.report({ node, - message: `Use the following Backpack token instead: ${expectedToken.name}`, - fix: fixer => { - const { options: userOptions } = context; - const options = _.merge({}, BASE_CONFIG, userOptions[0] || {}); - const tokensPkg = options.tokensPackage[options.platform]; - - if (!options.autoImport) { - return fixer.replaceText(value, expectedToken.name); - } - - const importDefinition = getImportDefinition(node, expectedToken.name, { - packageName: tokensPkg, - style: 'named', - }); - - if (importDefinition.isImported) { - return fixer.replaceText(value, expectedToken.name); - } - - return [ - addImport(fixer, importDefinition), - fixer.replaceText(value, expectedToken.name), - ]; - }, + message: `Multiple colors matched for colour, refer to to https://www.skyscanner.design/latest/foundations/colours/usage-LJ0uHGQL for the right semantic token`, + }); + } else if (matchedTokens.length === 0) { + context.report({ + node, + message: `Unknown color detected not in our brand, refer to to https://www.skyscanner.design/latest/foundations/colours/usage-LJ0uHGQL for the right semantic token`, }); } else { - if (COLOR_WHITELIST.filter(c => value.value === c).length) return; context.report({ node, - message: `Unknown color, use a Backpack token instead`, + message: `Use the following Backpack token instead: ${matchedTokens[0].name}`, }); } }; @@ -170,9 +115,7 @@ const isLiteralNumber = node => */ const isLengthIdentifier = node => node.type === 'Identifier' && - (SPACING_NAMES.has(node.name) || - RADII_NAMES.has(node.name) || - BORDER_NAMES.has(node.name)); + (RADII_NAMES.has(node.name) || BORDER_NAMES.has(node.name)); /* * Ensures that a complex expression i.e. not a literal is a @@ -242,9 +185,7 @@ const isValidComplexLengthExpression = node => { const checkLengths = (node, context) => { const { key, value } = node; const isLength = - SPACING_PROPS.includes(key.name) || - RADII_PROPS.includes(key.name) || - BORDER_PROPS.includes(key.name); + RADII_PROPS.includes(key.name) || BORDER_PROPS.includes(key.name); if (!isLength) { return; @@ -291,9 +232,6 @@ module.exports = { web: { type: 'string', }, - native: { - type: 'string', - }, }, additionalProperties: false, }, diff --git a/src/rules/use-tokens/use-tokens.test.js b/src/rules/use-tokens/use-tokens.test.js index 6477408..421d36a 100644 --- a/src/rules/use-tokens/use-tokens.test.js +++ b/src/rules/use-tokens/use-tokens.test.js @@ -27,271 +27,143 @@ const ruleTester = new RuleTester({ ruleTester.run('use-tokens', useTokens, { valid: [ `const styles = StyleSheet.create({ - foo: { - color: colorWhite, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - color: colorSkyBlue, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - backgroundColor: colorWhite, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - backgroundColor: 'transparent', - }, - });`, - `const styles = StyleSheet.create({ - foo: { - backgroundColor: null, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - backgroundColor: undefined, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - marginLeft: spacingSm, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - borderBottomStartRadius: spacingSm, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - borderBottomStartRadius: 0, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - marginLeft: spacingSm * 4, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - marginLeft: spacingSm * 5 * 3, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - marginLeft: (spacingSm * 5) * spacingBase, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - marginLeft: bar * 5, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - marginLeft: myMargin() * 5, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - marginLeft: spacingSm + spacingSm, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - paddingHorizontal: spacingMd - borderSizeSm, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - minHeight: spacingBase * 3, - }, - });`, - `const styles = StyleSheet.create({ - foo: { - borderRadius: borderRadiusSm, - }, - });`, + foo: { + color: canvasDay, + }, + });`, + `const styles = StyleSheet.create({ + foo: { + color: colorSkyBlue, + }, + });`, + `const styles = StyleSheet.create({ + foo: { + backgroundColor: canvasDay, + }, + });`, + `const styles = StyleSheet.create({ + foo: { + backgroundColor: 'transparent', + }, + });`, + `const styles = StyleSheet.create({ + foo: { + backgroundColor: null, + }, + });`, + `const styles = StyleSheet.create({ + foo: { + backgroundColor: undefined, + }, + });`, + `const styles = StyleSheet.create({ + foo: { + borderBottomStartRadius: 0, + }, + });`, + `const styles = StyleSheet.create({ + foo: { + marginLeft: bar * 5, + }, + });`, + `const styles = StyleSheet.create({ + foo: { + marginLeft: myMargin() * 5, + }, + });`, + `const styles = StyleSheet.create({ + foo: { + borderRadius: borderRadiusSm, + }, + });`, + `const styles = StyleSheet.create({ + foo: { + padding: 5, + }, + });`, ], invalid: [ { code: ` -const styles = StyleSheet.create({ - foo: { - color: '#ffffff', - }, -});`, - output: ` -import { colorWhite } from 'bpk-tokens/tokens/base.es6'; - -const styles = StyleSheet.create({ - foo: { - color: colorWhite, - }, -});`, - errors: [ - { - message: 'Use the following Backpack token instead: colorWhite', - }, - ], - }, - { - code: ` -const styles = StyleSheet.create({ - foo: { - backgroundColor: '#ff00ff', - color: '#ff00ff', - }, -});`, - errors: [ - { - message: 'Unknown color, use a Backpack token instead', - }, - { - message: 'Unknown color, use a Backpack token instead', - }, - ], - }, - - { - code: ` -const styles = StyleSheet.create({ - foo: { - backgroundColor: '#ffffff', - }, -});`, - output: ` -import { colorWhite } from 'bpk-tokens/tokens/base.es6'; - -const styles = StyleSheet.create({ - foo: { - backgroundColor: colorWhite, - }, -});`, + const styles = StyleSheet.create({ + foo: { + color: 'rgba(0, 0, 0, 0.8)', + }, + });`, errors: [ { - message: 'Use the following Backpack token instead: colorWhite', + message: + 'Use the following Backpack token instead: privateMapMarkerViewedForegroundNight', }, ], }, - { code: ` -const styles = StyleSheet.create({ - foo: { - color: 'rgb(7, 112, 227)', - }, -});`, - output: ` -import { colorPrimaryGradientLight } from 'bpk-tokens/tokens/base.es6'; - -const styles = StyleSheet.create({ - foo: { - color: colorPrimaryGradientLight, - }, -});`, + const styles = StyleSheet.create({ + foo: { + color: '#ffffff', + }, + });`, errors: [ { message: - 'Use the following Backpack token instead: colorPrimaryGradientLight', + 'Multiple colors matched for colour, refer to to https://www.skyscanner.design/latest/foundations/colours/usage-LJ0uHGQL for the right semantic token', }, ], }, - { - options: [{ autoImport: false }], code: ` -const styles = StyleSheet.create({ - foo: { - color: 'rgb(7, 112, 227)', - }, -});`, - output: ` -const styles = StyleSheet.create({ - foo: { - color: colorPrimaryGradientLight, - }, -});`, + const styles = StyleSheet.create({ + foo: { + backgroundColor: '#ff00ff', + color: '#ff00ff', + }, + });`, errors: [ { message: - 'Use the following Backpack token instead: colorPrimaryGradientLight', + 'Unknown color detected not in our brand, refer to to https://www.skyscanner.design/latest/foundations/colours/usage-LJ0uHGQL for the right semantic token', }, - ], - }, - - { - options: [{ platform: 'native' }], - code: ` -const styles = StyleSheet.create({ - foo: { - color: 'rgb(7, 112, 227)', - }, -});`, - output: ` -import { colorPrimaryGradientLight } from 'bpk-tokens/tokens/base.react.native'; - -const styles = StyleSheet.create({ - foo: { - color: colorPrimaryGradientLight, - }, -});`, - errors: [ { message: - 'Use the following Backpack token instead: colorPrimaryGradientLight', + 'Unknown color detected not in our brand, refer to to https://www.skyscanner.design/latest/foundations/colours/usage-LJ0uHGQL for the right semantic token', }, ], }, - { - options: [{ platform: 'native', tokensPackage: { native: './tokens' } }], code: ` -const styles = StyleSheet.create({ - foo: { - color: 'rgb(7, 112, 227)', - }, -});`, - output: ` -import { colorPrimaryGradientLight } from './tokens'; - -const styles = StyleSheet.create({ - foo: { - color: colorPrimaryGradientLight, - }, -});`, + const styles = StyleSheet.create({ + foo: { + backgroundColor: '#ffffff', + }, + });`, errors: [ { message: - 'Use the following Backpack token instead: colorPrimaryGradientLight', + 'Multiple colors matched for colour, refer to to https://www.skyscanner.design/latest/foundations/colours/usage-LJ0uHGQL for the right semantic token', }, ], }, - { - code: `const styles = StyleSheet.create({ - foo: { - marginLeft: 4, - }, - });`, + code: ` + const styles = StyleSheet.create({ + foo: { + color: 'rgb(7, 112, 227)', + }, + });`, errors: [ { message: - "Don't use raw numbers for `marginLeft` instead use a Backpack token or multiples of a token", + 'Unknown color detected not in our brand, refer to to https://www.skyscanner.design/latest/foundations/colours/usage-LJ0uHGQL for the right semantic token', }, ], }, - { code: `const styles = StyleSheet.create({ - foo: { - borderBottomStartRadius: 4, - }, - });`, + foo: { + borderBottomStartRadius: 4, + }, + });`, errors: [ { message: @@ -299,49 +171,6 @@ const styles = StyleSheet.create({ }, ], }, - - { - code: `const styles = StyleSheet.create({ - foo: { - marginLeft: spacingSm * 4 + 4, - }, - });`, - errors: [ - { - message: - "Don't use raw numbers for `marginLeft` instead use a Backpack token or multiples of a token", - }, - ], - }, - - { - code: `const styles = StyleSheet.create({ - foo: { - marginLeft: spacingSm * 4 + spacingBase + 2, - }, - });`, - errors: [ - { - message: - "Don't use raw numbers for `marginLeft` instead use a Backpack token or multiples of a token", - }, - ], - }, - - { - code: `const styles = StyleSheet.create({ - foo: { - marginLeft: 5 * 4, - }, - });`, - errors: [ - { - message: - "Don't use raw numbers for `marginLeft` instead use a Backpack token or multiples of a token", - }, - ], - }, - { code: `const styles = StyleSheet.create({ foo: { @@ -355,7 +184,6 @@ const styles = StyleSheet.create({ }, ], }, - { code: `const styles = StyleSheet.create({ foo: {