diff --git a/docs/migrating.storybook.mdx b/docs/migrating.storybook.mdx index 93c840e24..ed2fcf986 100644 --- a/docs/migrating.storybook.mdx +++ b/docs/migrating.storybook.mdx @@ -53,6 +53,15 @@ This won't change how your icons look in any way since we already exported the d npx jscodeshift -t node_modules/@freenow/wave/lib/cjs/codemods/deprecated-icons.js path/to/src ``` +### Text weak property + +The `weak` property was the initial way to indicate secondary information in a `Text` component, it has been deprecated for a while in favour of +the more semantic `secondary` prop. + +```bash +npx jscodeshift -t node_modules/@freenow/wave/lib/cjs/codemods/weak-to-secondary.js path/to/src +``` + ### Tooltip placement property In a previous minor release we swapped our positioning engine from `react-tether` to `react-popper`, this came with changes in the placement options @@ -66,3 +75,4 @@ npx jscodeshift -t node_modules/@freenow/wave/lib/cjs/codemods/tooltip-placement You can find the mappings in the following table: + diff --git a/src/codemods/__testfixtures__/block-to-width-100.output.tsx b/src/codemods/__testfixtures__/block-to-width-100.output.tsx index c1833e9b6..08218ab00 100644 --- a/src/codemods/__testfixtures__/block-to-width-100.output.tsx +++ b/src/codemods/__testfixtures__/block-to-width-100.output.tsx @@ -2,7 +2,7 @@ import { Button } from '@freenow/wave'; import React from 'react'; export const ButtonTest = (): JSX.Element => ( - ); diff --git a/src/codemods/__testfixtures__/weak-to-secondary/basic-usage.input.tsx b/src/codemods/__testfixtures__/weak-to-secondary/basic-usage.input.tsx new file mode 100644 index 000000000..1647c4678 --- /dev/null +++ b/src/codemods/__testfixtures__/weak-to-secondary/basic-usage.input.tsx @@ -0,0 +1,7 @@ +import { Text } from '@freenow/wave'; + +export const TextTest = () => ( + + Just a text + +); diff --git a/src/codemods/__testfixtures__/weak-to-secondary/basic-usage.output.tsx b/src/codemods/__testfixtures__/weak-to-secondary/basic-usage.output.tsx new file mode 100644 index 000000000..b9d1ac9d0 --- /dev/null +++ b/src/codemods/__testfixtures__/weak-to-secondary/basic-usage.output.tsx @@ -0,0 +1,7 @@ +import { Text } from '@freenow/wave'; + +export const TextTest = () => ( + + Just a text + +); diff --git a/src/codemods/__testfixtures__/weak-to-secondary/boolean-false.input.tsx b/src/codemods/__testfixtures__/weak-to-secondary/boolean-false.input.tsx new file mode 100644 index 000000000..809ad9921 --- /dev/null +++ b/src/codemods/__testfixtures__/weak-to-secondary/boolean-false.input.tsx @@ -0,0 +1,7 @@ +import { Text } from '@freenow/wave'; + +export const TextTest = () => ( + + Just a text + +); diff --git a/src/codemods/__testfixtures__/weak-to-secondary/boolean-false.output.tsx b/src/codemods/__testfixtures__/weak-to-secondary/boolean-false.output.tsx new file mode 100644 index 000000000..cb3fde51b --- /dev/null +++ b/src/codemods/__testfixtures__/weak-to-secondary/boolean-false.output.tsx @@ -0,0 +1,7 @@ +import { Text } from '@freenow/wave'; + +export const TextTest = () => ( + + Just a text + +); diff --git a/src/codemods/__testfixtures__/weak-to-secondary/boolean-true.input.tsx b/src/codemods/__testfixtures__/weak-to-secondary/boolean-true.input.tsx new file mode 100644 index 000000000..75160a6bd --- /dev/null +++ b/src/codemods/__testfixtures__/weak-to-secondary/boolean-true.input.tsx @@ -0,0 +1,7 @@ +import { Text } from '@freenow/wave'; + +export const TextTest = () => ( + + Just a text + +); diff --git a/src/codemods/__testfixtures__/weak-to-secondary/boolean-true.output.tsx b/src/codemods/__testfixtures__/weak-to-secondary/boolean-true.output.tsx new file mode 100644 index 000000000..b9d1ac9d0 --- /dev/null +++ b/src/codemods/__testfixtures__/weak-to-secondary/boolean-true.output.tsx @@ -0,0 +1,7 @@ +import { Text } from '@freenow/wave'; + +export const TextTest = () => ( + + Just a text + +); diff --git a/src/codemods/__testfixtures__/weak-to-secondary/dynamic-value.input.tsx b/src/codemods/__testfixtures__/weak-to-secondary/dynamic-value.input.tsx new file mode 100644 index 000000000..869c4f9ab --- /dev/null +++ b/src/codemods/__testfixtures__/weak-to-secondary/dynamic-value.input.tsx @@ -0,0 +1,7 @@ +import { Text } from '@freenow/wave'; + +export const TextTest = () => ( + + Just a text + +); diff --git a/src/codemods/__testfixtures__/weak-to-secondary/dynamic-value.output.tsx b/src/codemods/__testfixtures__/weak-to-secondary/dynamic-value.output.tsx new file mode 100644 index 000000000..e9d34b6af --- /dev/null +++ b/src/codemods/__testfixtures__/weak-to-secondary/dynamic-value.output.tsx @@ -0,0 +1,7 @@ +import { Text } from '@freenow/wave'; + +export const TextTest = () => ( + + Just a text + +); diff --git a/src/codemods/__testfixtures__/weak-to-secondary/local-rename.input.tsx b/src/codemods/__testfixtures__/weak-to-secondary/local-rename.input.tsx new file mode 100644 index 000000000..d69c875c5 --- /dev/null +++ b/src/codemods/__testfixtures__/weak-to-secondary/local-rename.input.tsx @@ -0,0 +1,7 @@ +import { Text as WaveText } from '@freenow/wave'; + +export const TextTest = () => ( + + Just a text + +); diff --git a/src/codemods/__testfixtures__/weak-to-secondary/local-rename.output.tsx b/src/codemods/__testfixtures__/weak-to-secondary/local-rename.output.tsx new file mode 100644 index 000000000..ce2eeb4ea --- /dev/null +++ b/src/codemods/__testfixtures__/weak-to-secondary/local-rename.output.tsx @@ -0,0 +1,7 @@ +import { Text as WaveText } from '@freenow/wave'; + +export const TextTest = () => ( + + Just a text + +); diff --git a/src/codemods/__tests__/weak-to-secondary-test.ts b/src/codemods/__tests__/weak-to-secondary-test.ts new file mode 100644 index 000000000..461b9c39d --- /dev/null +++ b/src/codemods/__tests__/weak-to-secondary-test.ts @@ -0,0 +1,12 @@ +jest.autoMockOff(); +const { defineTest } = require('jscodeshift/dist/testUtils'); + +const tests = ['basic-usage', 'local-rename', 'boolean-true', 'boolean-false', 'dynamic-value']; + +describe('weak-to-secondary', () => { + tests.forEach(test => + defineTest(__dirname, 'weak-to-secondary', { quote: 'single' }, `weak-to-secondary/${test}`, { + parser: 'tsx' + }) + ); +}); diff --git a/src/codemods/weak-to-secondary.ts b/src/codemods/weak-to-secondary.ts new file mode 100644 index 000000000..da273e625 --- /dev/null +++ b/src/codemods/weak-to-secondary.ts @@ -0,0 +1,67 @@ +import { API, ASTPath, FileInfo, JSXIdentifier } from 'jscodeshift'; +import { Options } from 'recast'; + +module.exports = (file: FileInfo, api: API, options: Options) => { + const j = api.jscodeshift; + const ast = j(file.source); + const printOptions = options ?? { quote: 'single' }; + + const localTextNames = []; + + const secondaryProp = { + type: 'JSXAttribute', + name: 'secondary' + }; + + // Find Wave Text imports and store the local names + ast.find(j.ImportDeclaration, decl => decl.source.value === '@freenow/wave').forEach(decl => { + j(decl) + .find(j.ImportSpecifier) + .forEach(spec => { + if (spec.node.imported.name === 'Text') localTextNames.push(spec.node.local.name); + }); + }); + + // Search for usages of Text + ast.find(j.JSXElement, { + openingElement: { + name: { + name: name => localTextNames.includes(name) + } + } + }).forEach(el => { + j(el) + // Find weak props being used + .find(j.JSXAttribute, { + name: name => name.name === 'weak' + }) + .forEach(attr => { + const mutableAttr = j(attr); + + // Find the identifier (where the prop name is kept) + const identifier: ASTPath = mutableAttr + .find(j.JSXIdentifier, { + name: 'weak' + }) + .get(0).node; + + // In case it has a boolean value (weak={false} or weak={true}) + if ( + attr.node.value?.type === 'JSXExpressionContainer' && + attr.node.value.expression.type === 'BooleanLiteral' + ) { + // If weak={true} replace with secondary prop + if (attr.node.value.expression.value) mutableAttr.replaceWith(secondaryProp); + // Otherwise (weak={false}) remove altogether + else mutableAttr.remove(); + return; + } + + // For other cases, e.g. implicit value (weak), dynamic value (weak={Date.now() % 2 === 0}) + // Replace the name of the prop + identifier.name = 'secondary'; + }); + }); + + return ast.toSource(printOptions); +}; diff --git a/src/components/Text/Text.tsx b/src/components/Text/Text.tsx index e21b9b58e..87b519697 100644 --- a/src/components/Text/Text.tsx +++ b/src/components/Text/Text.tsx @@ -15,7 +15,6 @@ import { } from 'styled-system'; import { theme } from '../../essentials/theme'; import { get } from '../../utils/themeGet'; -import { deprecatedProperty } from '../../utils/deprecatedProperty'; import { getSemanticValue } from '../../utils/cssVariables'; interface TextProps @@ -33,11 +32,6 @@ interface TextProps * Adjust color for display on a dark background */ inverted?: boolean; - /** - * Adjust color to indicate secondary information - * @deprecated use `secondary` instead - */ - weak?: boolean; /** * Adjust color to indicate secondary information */ @@ -49,16 +43,12 @@ interface TextProps } function determineTextColor(props: TextProps) { - const { weak, secondary, inverted, disabled } = props; - if (weak !== undefined) { - deprecatedProperty('Text', weak, 'weak', 'secondary', 'Rename `weak` to `secondary` to remove the warning.'); - } - + const { secondary, inverted, disabled } = props; if (disabled) { return getSemanticValue('foreground-disabled'); } - if (secondary || weak) { + if (secondary) { return getSemanticValue(inverted ? 'foreground-neutral-faded' : 'foreground-neutral-emphasized'); } diff --git a/src/components/Text/docs/Text.stories.tsx b/src/components/Text/docs/Text.stories.tsx index 13b31cd41..67758229b 100644 --- a/src/components/Text/docs/Text.stories.tsx +++ b/src/components/Text/docs/Text.stories.tsx @@ -52,11 +52,6 @@ const meta: Meta = { disable: true } }, - weak: { - table: { - disable: true - } - } }, args: { children: 'Sign up to FREENOW'