Skip to content

Commit

Permalink
Create codemod to replace deprecated icons (#364)
Browse files Browse the repository at this point in the history
* chore: bump jscodeshift to 0.15.0

* test: cover block property transform

* feat: replace colors in template string for css vars

* fix: adapt codemod to cover templates with an even number of quasis

* chore: add single quote config option to block codemod

* build: include codemods in build

* docs: add new codemod info in migrating docs

* feat: add codemod for deprecated icons replacement

* chore: remove deprecated icons folder

* refactor: simplify constants in deprecated icons codemod

* docs: add semantic tokens recommendation in migration docs

* docs: add description for deprecated icons codemod
  • Loading branch information
martimalek committed Aug 29, 2023
1 parent 0c6c9ab commit e12b891
Show file tree
Hide file tree
Showing 33 changed files with 182 additions and 204 deletions.
11 changes: 10 additions & 1 deletion docs/migrating.storybook.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ allow jscodeshift to parse your typescript/jsx files.

## From v1 to v2

Two codemods exist to upgrade your components for version 2. In order to apply the transformations in your project you simply need to run the
The following codemods exist to upgrade your components for version 2. In order to apply the transformations in your project you simply need to run the
command for your desired codemod pointing to your project's source path.

### Button and TextButton block property
Expand All @@ -41,3 +41,12 @@ npx jscodeshift -t node_modules/@freenow/wave/lib/cjs/codemods/colors-to-css-var

Disclaimer: This codemod transforms usages of `Colors` to our bare colors CSS variables to ensure we don't introduce breaking changes, that being said,
we recommend using semantic tokens instead as a best practice and offer a `getSemanticValue` API for just that.

### Deprecated icons

We had some deprecated icons that have been deleted in this major, in case you used any of them you need to use their valid (non-deprecated) counterpart from now on.
This won't change how your icons look in any way since we already exported the deprecated icons as wrappers of valid ones.

```bash
npx jscodeshift -t node_modules/@freenow/wave/lib/cjs/codemods/deprecated-icons.js path/to/src
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { IconProps, ForwardSmallIcon, SearchSmallIcon } from '@freenow/wave';

export enum CampaignType {
REGULAR = 'REGULAR',
AUTOMATION = 'AUTOMATION'
}

export const CampaignTypeOptions: { icon: React.FC<IconProps>; type: CampaignType }[] = [
{ icon: ForwardSmallIcon, type: CampaignType.REGULAR },
{ icon: SearchSmallIcon, type: CampaignType.AUTOMATION }
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { IconProps, ForwardLastIcon, MagnifyingGlassIcon } from '@freenow/wave';

export enum CampaignType {
REGULAR = 'REGULAR',
AUTOMATION = 'AUTOMATION'
}

export const CampaignTypeOptions: { icon: React.FC<IconProps>; type: CampaignType }[] = [
{ icon: ForwardLastIcon, type: CampaignType.REGULAR },
{ icon: MagnifyingGlassIcon, type: CampaignType.AUTOMATION }
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Box, BackwardSmallIcon, ChevronDownSmallIcon, Text } from '@freenow/wave';

interface Props {
name: string;
}

const AutomationIcon = () => <BackwardSmallIcon data-testid="automation-campaign-icon" />;

export const Automation = ({ name }: Props) => (
<Box display="flex" alignItems="center">
<AutomationIcon />
<ChevronDownSmallIcon />
<Text fontSize="small">{name}</Text>
</Box>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Box, BackwardLastIcon, ChevronDownIcon, Text } from '@freenow/wave';

interface Props {
name: string;
}

const AutomationIcon = () => <BackwardLastIcon data-testid="automation-campaign-icon" />;

export const Automation = ({ name }: Props) => (
<Box display="flex" alignItems="center">
<AutomationIcon />
<ChevronDownIcon />
<Text fontSize="small">{name}</Text>
</Box>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Box, BackwardSmallIcon, Text } from '@freenow/wave';

interface Props {
name: string;
}

const AutomationIcon = () => <BackwardSmallIcon data-testid="automation-campaign-icon" />;

export const Automation = ({ name }: Props) => (
<Box display="flex" alignItems="center">
<AutomationIcon />
<Text fontSize="small">{name}</Text>
</Box>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Box, BackwardLastIcon, Text } from '@freenow/wave';

interface Props {
name: string;
}

const AutomationIcon = () => <BackwardLastIcon data-testid="automation-campaign-icon" />;

export const Automation = ({ name }: Props) => (
<Box display="flex" alignItems="center">
<AutomationIcon />
<Text fontSize="small">{name}</Text>
</Box>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ChevronLeftSmallIcon, themeGet } from '@freenow/wave';
import styled from 'styled-components';

export const StyledIcon = styled(ChevronLeftSmallIcon).attrs({ size: 16 })`
fill: ${themeGet('semanticColors.icon.tertiary')};
margin-left: auto;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ChevronLeftIcon, themeGet } from '@freenow/wave';
import styled from 'styled-components';

export const StyledIcon = styled(ChevronLeftIcon).attrs({ size: 16 })`
fill: ${themeGet('semanticColors.icon.tertiary')};
margin-left: auto;
`;
2 changes: 0 additions & 2 deletions src/codemods/__tests__/block-to-width-100-test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// import { defineTest } from 'jscodeshift/dist/testUtils'

jest.autoMockOff();
const { defineTest } = require('jscodeshift/dist/testUtils');

Expand Down
12 changes: 12 additions & 0 deletions src/codemods/__tests__/deprecated-icons-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 = ['jsx-usage-single-import', 'jsx-usage-multi-import', 'styled-usage', 'constant-usage'];

describe('deprecated-icons', () => {
tests.forEach(test =>
defineTest(__dirname, 'deprecated-icons', { quote: 'single' }, `deprecated-icons/${test}`, {
parser: 'tsx'
})
);
});
66 changes: 66 additions & 0 deletions src/codemods/deprecated-icons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { API, FileInfo } from 'jscodeshift';
import { Options } from 'recast';

const DeprecatedToValidIconsMap = {
BackwardSmallIcon: 'BackwardLastIcon',
ChevronDownSmallIcon: 'ChevronDownIcon',
ChevronLeftSmallIcon: 'ChevronLeftIcon',
ChevronRightSmallIcon: 'ChevronRightIcon',
ChevronUpSmallIcon: 'ChevronUpIcon',
DownloadSmallIcon: 'DownloadIcon',
ForwardSmallIcon: 'ForwardLastIcon',
SearchSmallIcon: 'MagnifyingGlassIcon',
XSmallIcon: 'CloseIcon',
AirportIcon: 'PlaneIcon',
EcoIcon: 'LeafSolidIcon',
GearIcon: 'CogIcon',
HeartIcon: 'HeartSolidIcon',
HomeIcon: 'HouseIcon',
InfoCircleIcon: 'InfoCircleOutlineIcon',
ListUnorderedIcon: 'ListIcon',
PrebookingIcon: 'CalendarCheckedIcon',
SearchIcon: 'MagnifyingGlassIcon',
XIcon: 'CloseIcon'
};

const DeprecatedIconsNames = Array.from(Object.keys(DeprecatedToValidIconsMap));

export default (file: FileInfo, api: API, options: Options) => {
const j = api.jscodeshift;
const ast = j(file.source);
const printOptions = options ?? { quote: 'single' };

const localIconsNames: string[] = [];

// Find @freenow/wave imports
const waveImports = ast.find(j.ImportDeclaration, {
source: {
value: '@freenow/wave'
}
});

// Find deprecated icons named imports in @freenow/wave imports
const deprecatedIconsImports = waveImports
.find(j.ImportSpecifier)
.filter(path => DeprecatedIconsNames.includes(path.node.imported.name));

// Get the local icons import names
deprecatedIconsImports.forEach(spec => {
if (spec.node.local?.name) localIconsNames.push(spec.node.local.name);
});

// Find usages of the deprecated icons
const iconsIdentifiers = ast.find(j.Identifier, {
name: (name: string) => localIconsNames.includes(name)
});

// Iterate over deprecated usages and replace for valid ones, this includes imports
iconsIdentifiers.forEach(id => {
const validIconName: string = DeprecatedToValidIconsMap[id.node.name];
if (!validIconName) return;

id.node.name = validIconName;
});

return ast.toSource(printOptions);
};
9 changes: 0 additions & 9 deletions src/icons/deprecated/AirportIcon.tsx

This file was deleted.

9 changes: 0 additions & 9 deletions src/icons/deprecated/BackwardSmallIcon.tsx

This file was deleted.

13 changes: 0 additions & 13 deletions src/icons/deprecated/ChevronDownSmallIcon.tsx

This file was deleted.

11 changes: 0 additions & 11 deletions src/icons/deprecated/ChevronLeftSmallIcon.tsx

This file was deleted.

11 changes: 0 additions & 11 deletions src/icons/deprecated/ChevronRightSmallIcon.tsx

This file was deleted.

9 changes: 0 additions & 9 deletions src/icons/deprecated/ChevronUpSmallIcon.tsx

This file was deleted.

9 changes: 0 additions & 9 deletions src/icons/deprecated/DownloadSmallIcon.tsx

This file was deleted.

9 changes: 0 additions & 9 deletions src/icons/deprecated/EcoIcon.tsx

This file was deleted.

9 changes: 0 additions & 9 deletions src/icons/deprecated/ForwardSmallIcon.tsx

This file was deleted.

9 changes: 0 additions & 9 deletions src/icons/deprecated/GearIcon.tsx

This file was deleted.

9 changes: 0 additions & 9 deletions src/icons/deprecated/HeartIcon.tsx

This file was deleted.

9 changes: 0 additions & 9 deletions src/icons/deprecated/HomeIcon.tsx

This file was deleted.

9 changes: 0 additions & 9 deletions src/icons/deprecated/InfoCircleIcon.tsx

This file was deleted.

9 changes: 0 additions & 9 deletions src/icons/deprecated/ListUnorderedIcon.tsx

This file was deleted.

10 changes: 0 additions & 10 deletions src/icons/deprecated/PrebookingIcon.tsx

This file was deleted.

9 changes: 0 additions & 9 deletions src/icons/deprecated/SearchIcon.tsx

This file was deleted.

9 changes: 0 additions & 9 deletions src/icons/deprecated/SearchSmallIcon.tsx

This file was deleted.

9 changes: 0 additions & 9 deletions src/icons/deprecated/XIcon.tsx

This file was deleted.

Loading

0 comments on commit e12b891

Please sign in to comment.