Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): add prop codemods #600

Merged
merged 7 commits into from
Jun 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,16 @@ module.exports = require('@sumup/foundry/eslint')(
rules: {
'import/no-unresolved': 'off',
'notice/notice': 'off',
'@typescript-eslint/no-unused-vars': 'off'
'@typescript-eslint/no-unused-vars': 'off',
'prettier/prettier': 'off'
}
},
{
files: ['src/cli/migrate/*.ts'],
rules: {
// jscodeshift expect no return value for files
// that should not be transformed.
'consistent-return': 'off'
}
}
]
Expand Down
35 changes: 35 additions & 0 deletions src/cli/migrate/__testfixtures__/as-prop.input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import styled from '@emotion/styled';
import { Heading, SubHeading, Text, Input } from '@sumup/circuit-ui';

const BaseHeading = () => <Heading element="h1" />;

const RedHeading = styled(Heading)`
color: red;
`;

const StyledHeading = () => <RedHeading element="h1" />;

const BaseSubHeading = () => <SubHeading element="h1" />;

const RedSubHeading = styled(SubHeading)`
color: red;
`;

const StyledSubHeading = () => <RedSubHeading element="h1" />;

const BaseText = () => <Text element="h1" />;

const RedText = styled(Text)`
color: red;
`;

const StyledText = () => <RedText element="h1" />;

const BaseInput = () => <Input element="h1" />;

const RedInput = styled(Input)`
color: red;
`;

const StyledInput = () => <RedInput element="h1" />;
35 changes: 35 additions & 0 deletions src/cli/migrate/__testfixtures__/as-prop.output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import styled from '@emotion/styled';
import { Heading, SubHeading, Text, Input } from '@sumup/circuit-ui';

const BaseHeading = () => <Heading as="h1" />;

const RedHeading = styled(Heading)`
color: red;
`;

const StyledHeading = () => <RedHeading as="h1" />;

const BaseSubHeading = () => <SubHeading as="h1" />;

const RedSubHeading = styled(SubHeading)`
color: red;
`;

const StyledSubHeading = () => <RedSubHeading as="h1" />;

const BaseText = () => <Text as="h1" />;

const RedText = styled(Text)`
color: red;
`;

const StyledText = () => <RedText as="h1" />;

const BaseInput = () => <Input as="h1" />;

const RedInput = styled(Input)`
color: red;
`;

const StyledInput = () => <RedInput as="h1" />;
23 changes: 23 additions & 0 deletions src/cli/migrate/__testfixtures__/exit-animations.input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import styled from '@emotion/styled';
import { LoadingButton } from '@sumup/circuit-ui';

const BaseLoadingButton = () => (
<LoadingButton
exitAnimation={LoadingButton.ERROR}
onAnimationComplete={console.log}
exitAnimationDuration={300}
/>
);

const RedLoadingButton = styled(LoadingButton)`
color: red;
`;

const StyledLoadingButton = () => (
<RedLoadingButton
exitAnimation={LoadingButton.ERROR}
onAnimationComplete={console.log}
exitAnimationDuration={300}
/>
);
15 changes: 15 additions & 0 deletions src/cli/migrate/__testfixtures__/exit-animations.output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import styled from '@emotion/styled';
import { LoadingButton } from '@sumup/circuit-ui';

const BaseLoadingButton = () => (
<LoadingButton />
);

const RedLoadingButton = styled(LoadingButton)`
color: red;
`;

const StyledLoadingButton = () => (
<RedLoadingButton />
);
17 changes: 17 additions & 0 deletions src/cli/migrate/__testfixtures__/input-deepref-prop.input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React, { useRef } from 'react';
import styled from '@emotion/styled';
import { Input } from '@sumup/circuit-ui';

const Form = () => {
const ref = useRef(null);
return <Input deepRef={ref} />;
};

const RedInput = styled(Input)`
color: red;
`;

const RedForm = () => {
const ref = useRef(null);
return <RedInput deepRef={ref} />;
};
17 changes: 17 additions & 0 deletions src/cli/migrate/__testfixtures__/input-deepref-prop.output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React, { useRef } from 'react';
import styled from '@emotion/styled';
import { Input } from '@sumup/circuit-ui';

const Form = () => {
const ref = useRef(null);
return <Input ref={ref} />;
};

const RedInput = styled(Input)`
color: red;
`;

const RedForm = () => {
const ref = useRef(null);
return <RedInput ref={ref} />;
};
28 changes: 28 additions & 0 deletions src/cli/migrate/__testfixtures__/list-variant-enum.input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import styled from '@emotion/styled';
import { List, Text } from '@sumup/circuit-ui';

const Ordered = () => <List ordered>primary</List>;

const Unordered = () => <List unordered>Secondary</List>;

const RedList = styled(List)`
color: red;
`;

const BlueList = styled(List)`
color: blue;
`;

const BlueText = styled(Text)`
color: blue;
`;

const Styled = () => (
<>
<RedList ordered>Ordered red</RedList>
<BlueList unordered>Unordered blue</BlueList>
<Text ordered>Text</Text>
<BlueText unordered>Text blue</BlueText>
</>
);
28 changes: 28 additions & 0 deletions src/cli/migrate/__testfixtures__/list-variant-enum.output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import styled from '@emotion/styled';
import { List, Text } from '@sumup/circuit-ui';

const Ordered = () => <List variant="ordered">primary</List>;

const Unordered = () => <List variant="unordered">Secondary</List>;

const RedList = styled(List)`
color: red;
`;

const BlueList = styled(List)`
color: blue;
`;

const BlueText = styled(Text)`
color: blue;
`;

const Styled = () => (
<>
<RedList variant="ordered">Ordered red</RedList>
<BlueList variant="unordered">Unordered blue</BlueList>
<Text ordered>Text</Text>
<BlueText unordered>Text blue</BlueText>
</>
);
21 changes: 21 additions & 0 deletions src/cli/migrate/__testfixtures__/onchange-prop.input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import styled from '@emotion/styled';
import { RadioButton, Switch } from '@sumup/circuit-ui';

const BaseRadioButton = () => <RadioButton onToggle={console.log} checked />;

const RedRadioButton = styled(RadioButton)`
color: red;
`;

const StyledRadioButton = () => (
<RedRadioButton onToggle={console.log} checked />
);

const BaseSwitch = () => <Switch onToggle={console.log} checked />;

const RedSwitch = styled(Switch)`
color: red;
`;

const StyledSwitch = () => <RedSwitch onToggle={console.log} checked />;
21 changes: 21 additions & 0 deletions src/cli/migrate/__testfixtures__/onchange-prop.output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import styled from '@emotion/styled';
import { RadioButton, Switch } from '@sumup/circuit-ui';

const BaseRadioButton = () => <RadioButton onChange={console.log} checked />;

const RedRadioButton = styled(RadioButton)`
color: red;
`;

const StyledRadioButton = () => (
<RedRadioButton onChange={console.log} checked />
);

const BaseSwitch = () => <Switch onChange={console.log} checked />;

const RedSwitch = styled(Switch)`
color: red;
`;

const StyledSwitch = () => <RedSwitch onChange={console.log} checked />;
11 changes: 11 additions & 0 deletions src/cli/migrate/__testfixtures__/selector-props.input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import styled from '@emotion/styled';
import { Selector } from '@sumup/circuit-ui';

const BaseSelector = () => <Selector onClick={console.log} selected />;

const RedSelector = styled(Selector)`
color: red;
`;

const StyledSelector = () => <RedSelector onClick={console.log} selected />;
11 changes: 11 additions & 0 deletions src/cli/migrate/__testfixtures__/selector-props.output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import styled from '@emotion/styled';
import { Selector } from '@sumup/circuit-ui';

const BaseSelector = () => <Selector onChange={console.log} checked />;

const RedSelector = styled(Selector)`
color: red;
`;

const StyledSelector = () => <RedSelector onChange={console.log} checked />;
6 changes: 6 additions & 0 deletions src/cli/migrate/__tests__/transforms.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,9 @@ import { defineTest } from 'jscodeshift/dist/testUtils';
jest.autoMockOff();

defineTest(__dirname, 'button-variant-enum');
defineTest(__dirname, 'list-variant-enum');
defineTest(__dirname, 'onchange-prop');
defineTest(__dirname, 'as-prop');
defineTest(__dirname, 'selector-props');
defineTest(__dirname, 'exit-animations');
defineTest(__dirname, 'input-deepref-prop');
47 changes: 47 additions & 0 deletions src/cli/migrate/as-prop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Copyright 2020, SumUp 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.
*/

import { Transform, JSCodeshift, Collection } from 'jscodeshift';

import { renameJSXAttribute, findLocalNames } from './utils';

function transformFactory(
j: JSCodeshift,
root: Collection,
componentName: string
): void {
const components = findLocalNames(j, root, componentName);

if (!components) {
return;
}

components.forEach(component => {
renameJSXAttribute(j, root, component, 'element', 'as');
});
}

const transform: Transform = (file, api) => {
const j = api.jscodeshift;
const root = j(file.source);

['Heading', 'SubHeading', 'Text', 'Input'].forEach(componentName => {
transformFactory(j, root, componentName);
});

return root.toSource();
};

export default transform;
14 changes: 3 additions & 11 deletions src/cli/migrate/button-variant-enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,19 @@

import { Transform, JSCodeshift, Collection } from 'jscodeshift';

import { findImportsByPath, findStyledComponentNames } from './utils';
import { findLocalNames } from './utils';

function transformFactory(
j: JSCodeshift,
root: Collection,
buttonName: string
): void {
const imports = findImportsByPath(j, root, '@sumup/circuit-ui');
const components = findLocalNames(j, root, buttonName);

const buttonImport = imports.find(i => i.name === buttonName);

if (!buttonImport) {
if (!components) {
return;
}

const localName = buttonImport.local;

const styledButtons = findStyledComponentNames(j, root, localName);

const components = [localName, ...styledButtons];

components.forEach(component => {
// Change variants from boolean to enum prop
['primary', 'secondary'].forEach(variant => {
Expand Down
Loading