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 : Implement codemod to rename slug prop to aiLabel for IBM Products components #17966

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React, { useState } from 'react';
import { Tearsheet } from '@carbon/ibm-products';
import {
Button,
Tabs,
TabList,
Tab,
AILabel,
AILabelContent,
} from '@carbon/react';

import './_example.scss';

export const Example = () => {
const [isOpen, setIsOpen] = useState(true);
const handleOpenModalClick = () => {
setIsOpen(true);
};
const handleCloseModal = () => {
setIsOpen(false);
};
const sampleAILabel = (
<AILabel className="ai-label-container" size="xs">
<AILabelContent>
<div>
<p className="secondary">AI Explained</p>
<h1>84%</h1>
<p className="secondary bold">Confidence score</p>
<p className="secondary">
This is not really Lorem Ipsum but the spell checker did not like
the previous text with it&apos;s non-words which is why this
unwieldy sentence, should one choose to call it that, here.
</p>
<hr />
<p className="secondary">Model type</p>
<p className="bold">Foundation model</p>
</div>
</AILabelContent>
</AILabel>
);
return (
<>
<style>{`.exp-tearsheet { opacity: 0 };`}</style>
<Button onClick={handleOpenModalClick}>Reopen Tearsheet</Button>
<Tearsheet
actions={[
{
kind: 'secondary',
label: 'Cancel',
onClick: handleCloseModal,
},
{
kind: 'primary',
label: 'Create',
onClick: handleCloseModal,
},
]}
slug={sampleAILabel}
closeIconDescription="Close the tearsheet"
description={
// cspell:disable
<span>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor <strong>incididunt ut labore</strong> et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
</span>
// cspell:enable
}
influencer={
<div className="tearsheet-example__dummy-content-block">
Influencer
</div>
}
label="This is the label of the tearsheet"
navigation={
<div className="tearsheet-example__tabs">
<Tabs onSelectionChange={() => {}}>
<TabList aria-label="tab list">
<Tab>Tab 1</Tab>
<Tab>Tab 2</Tab>
<Tab>Tab 3</Tab>
<Tab>Tab 4</Tab>
</TabList>
</Tabs>
</div>
}
onClose={handleCloseModal}
open={isOpen}
preventCloseOnClickOutside
title="This is the title of the tearsheet">
<div className="tearsheet-example__dummy-content-block">
The main content of the Tearsheet should be placed here.
</div>
</Tearsheet>
</>
);
};

export default Example;
30 changes: 30 additions & 0 deletions packages/upgrade/src/upgrades.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,36 @@
});
},
},
{
name: 'ibm-products-slug-to-ailabel-prop',
description: 'Replaces slug prop with aiLabel',
migrate: async (options) => {
const transform = path.join(

Check warning on line 366 in packages/upgrade/src/upgrades.js

View check run for this annotation

Codecov / codecov/patch

packages/upgrade/src/upgrades.js#L365-L366

Added lines #L365 - L366 were not covered by tests
TRANSFORM_DIR,
'ibm-products-slug-to-ailabel-prop.js'
);
const paths =
Array.isArray(options.paths) && options.paths.length > 0
? options.paths
: await glob(['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx'], {

Check warning on line 373 in packages/upgrade/src/upgrades.js

View check run for this annotation

Codecov / codecov/patch

packages/upgrade/src/upgrades.js#L372-L373

Added lines #L372 - L373 were not covered by tests
cwd: options.workspaceDir,
ignore: [
'**/es/**',
'**/lib/**',
'**/umd/**',
'**/node_modules/**',
'**/storybook-static/**',
],
});

await run({

Check warning on line 384 in packages/upgrade/src/upgrades.js

View check run for this annotation

Codecov / codecov/patch

packages/upgrade/src/upgrades.js#L384

Added line #L384 was not covered by tests
dry: !options.write,
transform,
paths,
verbose: options.verbose,
});
},
},
],
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const sampleAILabel = (
<AILabel className="ai-label-container" size="xs">
<AILabelContent>
<div>
<p className="secondary">AI Explained</p>
<h1>84%</h1>
<p className="secondary bold">Confidence score</p>
<p className="secondary">test</p>
<hr />
<p className="secondary">Model type</p>
<p className="bold">Foundation model</p>
</div>
</AILabelContent>
</AILabel>
);

function Test1() {
return (
<Tearsheet className="test" slug={sampleAILabel}>
Test
</Tearsheet>
);
}

function Test2() {
return (
<SidePanel className="test" slug={sampleAILabel}>
Test
</SidePanel>
);
}

function Test3() {
return (
<ExpressiveCard className="test" slug={sampleAILabel}>
Test
</ExpressiveCard>
);
}

function Test4() {
return (
<ProductiveCard className="test" slug={sampleAILabel}>
Test
</ProductiveCard>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

const sampleAILabel = (
<AILabel className="ai-label-container" size="xs">
<AILabelContent>
<div>
<p className="secondary">AI Explained</p>
<h1>84%</h1>
<p className="secondary bold">Confidence score</p>
<p className="secondary">test</p>
<hr />
<p className="secondary">Model type</p>
<p className="bold">Foundation model</p>
</div>
</AILabelContent>
</AILabel>
);

function Test1() {
return (
(<Tearsheet className="test" aiLabel={sampleAILabel}>Test
</Tearsheet>)
);
}

function Test2() {
return (
(<SidePanel className="test" aiLabel={sampleAILabel}>Test
</SidePanel>)
);
}

function Test3() {
return (
(<ExpressiveCard className="test" aiLabel={sampleAILabel}>Test
</ExpressiveCard>)
);
}

function Test4() {
return (
(<ProductiveCard className="test" aiLabel={sampleAILabel}>Test
</ProductiveCard>)
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Copyright IBM Corp. 2016, 2023
*
* 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-slug-to-ailabel-prop');
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Copyright IBM Corp. 2016, 2023
*
* 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 defaultOptions = {
quote: 'auto',
trailingComma: true,
};

function transform(fileInfo, api, options) {
const printOptions = options.printOptions || defaultOptions;
const j = api.jscodeshift;
const root = j(fileInfo.source);

function replacePropForComponent(name) {
root
.find(j.JSXOpeningElement, {
name: {
name,
},
})
.forEach((openingElement) => {
j(openingElement)
.find(j.JSXAttribute, {
name: {
name: 'slug',
},
})
.forEach((path) => {
const slugValue = path.node.value;
const newAttribute = j.jsxAttribute(
j.jsxIdentifier('aiLabel'),
slugValue
);
j(path).replaceWith(newAttribute);
});
});
}

const components = [
'Tearsheet',
'SidePanel',
'ExpressiveCard',
'ProductiveCard',
];
for (const component of components) {
replacePropForComponent(component);
}

return root.toSource(printOptions);
}

module.exports = transform;
Loading