Skip to content

Commit

Permalink
feat!: remove weak prop from Text and add codemod for it (#374)
Browse files Browse the repository at this point in the history
* feat: add codemod for weak prop replacement in text

* docs: add migrating description of weak-to-secondary codemod

* feat: cover dynamic values in weak prop codemod and simplify it

* test: fix codemods tests styling

* chore: remove unused .prettierignore entry

* feat!: remove weak prop from Text
  • Loading branch information
martimalek authored Sep 29, 2023
1 parent b011ab0 commit df98bb9
Show file tree
Hide file tree
Showing 16 changed files with 162 additions and 18 deletions.
10 changes: 10 additions & 0 deletions docs/migrating.storybook.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:

<PlacementMappingsTable />

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Button } from '@freenow/wave';
import React from 'react';

export const ButtonTest = (): JSX.Element => (
<Button width="100%" mr="1" mt="3" disabled>
<Button width='100%' mr="1" mt="3" disabled>
Clone
</Button>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Text } from '@freenow/wave';

export const TextTest = () => (
<Text weak fontSize={1}>
Just a text
</Text>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Text } from '@freenow/wave';

export const TextTest = () => (
<Text secondary fontSize={1}>
Just a text
</Text>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Text } from '@freenow/wave';

export const TextTest = () => (
<Text weak={false} fontSize={1}>
Just a text
</Text>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Text } from '@freenow/wave';

export const TextTest = () => (
<Text fontSize={1}>
Just a text
</Text>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Text } from '@freenow/wave';

export const TextTest = () => (
<Text weak={true} fontSize={1}>
Just a text
</Text>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Text } from '@freenow/wave';

export const TextTest = () => (
<Text secondary fontSize={1}>
Just a text
</Text>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Text } from '@freenow/wave';

export const TextTest = () => (
<Text weak={Date.now() % 2 === 0} fontSize={1}>
Just a text
</Text>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Text } from '@freenow/wave';

export const TextTest = () => (
<Text secondary={Date.now() % 2 === 0} fontSize={1}>
Just a text
</Text>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Text as WaveText } from '@freenow/wave';

export const TextTest = () => (
<WaveText weak fontSize={1}>
Just a text
</WaveText>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Text as WaveText } from '@freenow/wave';

export const TextTest = () => (
<WaveText secondary fontSize={1}>
Just a text
</WaveText>
);
12 changes: 12 additions & 0 deletions src/codemods/__tests__/weak-to-secondary-test.ts
Original file line number Diff line number Diff line change
@@ -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'
})
);
});
67 changes: 67 additions & 0 deletions src/codemods/weak-to-secondary.ts
Original file line number Diff line number Diff line change
@@ -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<JSXIdentifier> = 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);
};
14 changes: 2 additions & 12 deletions src/components/Text/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
*/
Expand All @@ -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');
}

Expand Down
5 changes: 0 additions & 5 deletions src/components/Text/docs/Text.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,6 @@ const meta: Meta = {
disable: true
}
},
weak: {
table: {
disable: true
}
}
},
args: {
children: 'Sign up to FREENOW'
Expand Down

0 comments on commit df98bb9

Please sign in to comment.