Skip to content

Commit

Permalink
feat: implement codemod ibm-products-update-userprofileimage (#18058)
Browse files Browse the repository at this point in the history
* feat: implement codemod ibm-products-update-userprofileimage

* feat: implement codemod ibm-products-update-userprofileimage

* feat: implement codemod ibm-products-update-userprofileimage

* feat: implement codemod ibm-products-update-userprofileimage

* feat: implement codemod ibm-products-update-userprofileimage

* feat: implement codemod ibm-products-update-userprofileimage

* feat: implement codemod ibm-products-update-userprofileimage

* feat: implement codemod ibm-products-update-userprofileimage

* feat: implement codemod ibm-products-update-userprofileimage

* feat: implement codemod ibm-products-update-userprofileimage

* feat: implement codemod ibm-products-update-userprofileimage

* feat: codemod implementation removed sample file

---------

Co-authored-by: Nikhil Tomar <63502271+2nikhiltom@users.noreply.github.com>
  • Loading branch information
anamikaanu96 and 2nikhiltom authored Nov 20, 2024
1 parent c26e87d commit 2a594b7
Show file tree
Hide file tree
Showing 5 changed files with 256 additions and 0 deletions.
30 changes: 30 additions & 0 deletions packages/upgrade/src/upgrades.js
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,36 @@ export const upgrades = [
});
},
},
{
name: 'ibm-products-update-userprofileimage',
description: 'Rewrites UserProfileImage to UserAvatar',
migrate: async (options) => {
const transform = path.join(
TRANSFORM_DIR,
'ibm-products-update-userprofileimage.js'
);
const paths =
Array.isArray(options.paths) && options.paths.length > 0
? options.paths
: await glob(['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx'], {
cwd: options.workspaceDir,
ignore: [
'**/es/**',
'**/lib/**',
'**/umd/**',
'**/node_modules/**',
'**/storybook-static/**',
],
});

await run({
dry: !options.write,
transform,
paths,
verbose: options.verbose,
});
},
},
],
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import { UserProfileImage } from '@carbon/ibm-products';
import { Add } from '@carbon/react/icons';

const ImageUrl =
'https://img.freepik.com/free-photo/portrait-man-cartoon-style_23-2151133939.jpg?semt=ais_hybrid';

export const Example = () => (
<>
<UserProfileImage
size="md"
tooltipAlignment="bottom"
backgroundColor="light-purple"
theme="light"
tooltipText="Thomas Watson"
className="myClass"
initials="thomas j. watson"
/>
<UserProfileImage
size="md"
tooltipAlignment="bottom"
backgroundColor="light-purple"
theme="light"
tooltipText="Thomas Watson"
className="myClass"
kind="user"
/>
<UserProfileImage
size="md"
tooltipAlignment="bottom"
backgroundColor="light-purple"
theme="light"
tooltipText="Thomas Watson"
className="myClass"
icon={() => <Add size={20} />}
/>
<UserProfileImage
size="md"
tooltipAlignment="bottom"
backgroundColor="light-purple"
theme="light"
tooltipText="Thomas Watson"
className="myClass"
image={ImageUrl}
imageDescription="Avatar of Thomas Watson"
/>
</>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { User } from "@carbon/react/icons";
import React from 'react';
import { UserAvatar } from '@carbon/ibm-products';
import { Add } from '@carbon/react/icons';

const ImageUrl =
'https://img.freepik.com/free-photo/portrait-man-cartoon-style_23-2151133939.jpg?semt=ais_hybrid';

export const Example = () => (
<>
<UserAvatar
size="md"
tooltipAlignment="bottom"
backgroundColor="order-5-purple"
tooltipText="Thomas Watson"
className="myClass"
name="thomas j. watson" />
<UserAvatar
size="md"
tooltipAlignment="bottom"
backgroundColor="order-5-purple"
tooltipText="Thomas Watson"
className="myClass"
renderIcon={User} />
<UserAvatar
size="md"
tooltipAlignment="bottom"
backgroundColor="order-5-purple"
tooltipText="Thomas Watson"
className="myClass"
renderIcon={() => <Add size={20} />} />
<UserAvatar
size="md"
tooltipAlignment="bottom"
backgroundColor="order-5-purple"
tooltipText="Thomas Watson"
className="myClass"
image={ImageUrl}
imageDescription="Avatar of Thomas Watson" />
</>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Copyright IBM Corp. 2021, 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

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

defineTest(__dirname, 'ibm-products-update-userprofileimage');
125 changes: 125 additions & 0 deletions packages/upgrade/transforms/ibm-products-update-userprofileimage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/**
* Copyright IBM Corp. 2021, 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*
* Rewrites UserProfileImage to UserAvatar
*
* Transforms:
*
* <UserProfileImage />
*
* Into:
*
* <UserAvatar />
*/

'use strict';

const transform = (fileInfo, api) => {
const j = api.jscodeshift;
const root = j(fileInfo.source);
let shouldImportUser = false;
let shouldImportGroup = false;

const ensureImport = (identifierName) => {
const importDeclaration = j.importDeclaration(
[j.importSpecifier(j.identifier(identifierName))],
j.literal('@carbon/react/icons')
);

const existingImport = root
.find(j.ImportDeclaration, {
source: { value: '@carbon/react/icons' },
})
.filter((path) => {
return path.node.specifiers.some(
(specifier) => specifier.imported.name === identifierName
);
});

if (existingImport.size() === 0) {
root.find(j.Program).get('body', 0).insertBefore(importDeclaration);
}
};
// Transform UserProfileImage to UserAvatar
root
.find(j.JSXElement, {
openingElement: { name: { name: 'UserProfileImage' } },
})
.forEach((path) => {
// Change the component name
path.node.openingElement.name.name = 'UserAvatar';
if (path.node.closingElement) {
path.node.closingElement.name.name = 'UserAvatar';
}

const colorMapping = {
'light-cyan': 'order-1-cyan',
'dark-cyan': 'order-7-cyan',
'light-gray': 'order-2-gray',
'dark-gray': 'order-8-gray',
'light-green': 'order-3-green',
'dark-green': 'order-9-green',
'light-magenta': 'order-10-magenta',
'dark-magenta': 'order-10-magenta',
'light-purple': 'order-5-purple',
'dark-purple': 'order-11-purple',
'light-teal': 'order-6-teal',
'dark-teal': 'order-12-teal',
};
const updatedAttributes = [];
// Update attributes
path.node.openingElement.attributes.forEach((attr) => {
if (attr.name.name === 'backgroundColor') {
if (colorMapping[attr.value.value]) {
attr.value.value = colorMapping[attr.value.value];
}
}
if (attr.name.name === 'theme') {
return;
}
if (attr.name.name === 'initials') {
attr.name.name = 'name';
}
if (attr.name.name === 'kind' || attr.name.name === 'icon') {
const originalName = attr.name.name;
attr.name.name = 'renderIcon';
if (originalName === 'kind') {
if (attr.value.value === 'user') {
attr.value = j.jsxExpressionContainer(j.identifier('User'));
shouldImportUser = true;
} else if (attr.value.value === 'group') {
attr.value = j.jsxExpressionContainer(j.identifier('Group'));
shouldImportGroup = true;
}
}
}
updatedAttributes.push(attr);
});
path.node.openingElement.attributes = updatedAttributes;
});
// Update import statement
root
.find(j.ImportDeclaration)
.filter((path) => path.node.source.value === '@carbon/ibm-products')
.forEach((path) => {
path.node.specifiers.forEach((specifier) => {
if (specifier.imported.name === 'UserProfileImage') {
specifier.imported.name = 'UserAvatar';
}
});
});

if (shouldImportUser) {
ensureImport('User');
}

if (shouldImportGroup) {
ensureImport('Group');
}
return root.toSource();
};

module.exports = transform;

0 comments on commit 2a594b7

Please sign in to comment.