Skip to content

Commit

Permalink
Add codemod util and add examples
Browse files Browse the repository at this point in the history
  • Loading branch information
DiegoAndai committed Mar 27, 2024
1 parent 8e37d2b commit f837591
Show file tree
Hide file tree
Showing 18 changed files with 365 additions and 207 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import findComponentJSX from '../../util/findComponentJSX';
import assignObject from '../../util/assignObject';
import appendAttribute from '../../util/appendAttribute';
import movePropIntoSlots from '../utils/movePropIntoSlots';
import movePropIntoSlotProps from '../utils/movePropIntoSlotProps';

/**
* @param {import('jscodeshift').FileInfo} file
Expand All @@ -11,84 +10,18 @@ export default function transformer(file, api, options) {
const root = j(file.source);
const printOptions = options.printOptions;

findComponentJSX(j, { root, componentName: 'Accordion' }, (elementPath) => {
let index = elementPath.node.openingElement.attributes.findIndex(
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'TransitionComponent',
);
if (index !== -1) {
const removed = elementPath.node.openingElement.attributes.splice(index, 1);
let hasNode = false;
elementPath.node.openingElement.attributes.forEach((attr) => {
if (attr.name?.name === 'slots') {
hasNode = true;
assignObject(j, {
target: attr,
key: 'transition',
expression: removed[0].value.expression,
});
}
});
if (!hasNode) {
appendAttribute(j, {
target: elementPath.node,
attributeName: 'slots',
expression: j.objectExpression([
j.objectProperty(j.identifier('transition'), removed[0].value.expression),
]),
});
}
}

index = elementPath.node.openingElement.attributes.findIndex(
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'TransitionProps',
);
if (index !== -1) {
const removed = elementPath.node.openingElement.attributes.splice(index, 1);
let hasNode = false;
elementPath.node.openingElement.attributes.forEach((attr) => {
if (attr.name?.name === 'slotProps') {
hasNode = true;
assignObject(j, {
target: attr,
key: 'transition',
expression: removed[0].value.expression,
});
}
});
if (!hasNode) {
appendAttribute(j, {
target: elementPath.node,
attributeName: 'slotProps',
expression: j.objectExpression([
j.objectProperty(j.identifier('transition'), removed[0].value.expression),
]),
});
}
}
});

root.find(j.ObjectProperty, { key: { name: 'TransitionComponent' } }).forEach((path) => {
if (path.parent?.parent?.parent?.parent?.node.key?.name === 'MuiAccordion') {
path.replace(
j.property(
'init',
j.identifier('slots'),
j.objectExpression([j.objectProperty(j.identifier('transition'), path.node.value)]),
),
);
}
movePropIntoSlots(j, {
root,
componentName: 'Accordion',
propName: 'TransitionComponent',
slotName: 'transition',
});

root.find(j.ObjectProperty, { key: { name: 'TransitionProps' } }).forEach((path) => {
if (path.parent?.parent?.parent?.parent?.node.key?.name === 'MuiAccordion') {
path.replace(
j.property(
'init',
j.identifier('slotProps'),
j.objectExpression([j.objectProperty(j.identifier('transition'), path.node.value)]),
),
);
}
movePropIntoSlotProps(j, {
root,
componentName: 'Accordion',
propName: 'TransitionProps',
slotName: 'transition',
});

return root.toSource(printOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import { Accordion as MyAccordion } from '@mui/material';
...outerSlotProps,
}}
/>;
<Accordion TransitionComponent={ComponentTransition} slots={{ transition: SlotTransition }} />;
<Accordion TransitionProps={{ unmountOnExit: true }} slotProps={{ transition: { id: 'test' } }} />;
// should skip non MUI components
<NonMuiAccordion
TransitionComponent={CustomTransition}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ import { Accordion as MyAccordion } from '@mui/material';
...outerSlotProps,
transition: { unmountOnExit: true }
}} />;
<Accordion slots={{ transition: SlotTransition }} />;
<Accordion
slotProps={{ transition: {
...{ unmountOnExit: true },
...{ id: 'test' }
} }} />;
// should skip non MUI components
<NonMuiAccordion
TransitionComponent={CustomTransition}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,21 @@ fn({
},
},
});

fn({
MuiAccordion: {
defaultProps: {
TransitionComponent: ComponentTransition,
slots: { transition: SlotTransition },
},
},
});

fn({
MuiAccordion: {
defaultProps: {
slotProps: { transition: { id: 'test' } },
TransitionProps: { unmountOnExit: true },
},
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,22 @@ fn({
},
},
});

fn({
MuiAccordion: {
defaultProps: {
slots: { transition: SlotTransition }
},
},
});

fn({
MuiAccordion: {
defaultProps: {
slotProps: { transition: {
...{ unmountOnExit: true },
...{ id: 'test' }
} }
},
},
});
48 changes: 6 additions & 42 deletions packages/mui-codemod/src/deprecations/avatar-props/avatar-props.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import findComponentJSX from '../../util/findComponentJSX';
import assignObject from '../../util/assignObject';
import appendAttribute from '../../util/appendAttribute';
import movePropIntoSlotProps from '../utils/movePropIntoSlotProps';

/**
* @param {import('jscodeshift').FileInfo} file
Expand All @@ -11,45 +9,11 @@ export default function transformer(file, api, options) {
const root = j(file.source);
const printOptions = options.printOptions;

findComponentJSX(j, { root, componentName: 'Avatar' }, (elementPath) => {
const index = elementPath.node.openingElement.attributes.findIndex(
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'imgProps',
);
if (index !== -1) {
const removed = elementPath.node.openingElement.attributes.splice(index, 1);
let hasNode = false;
elementPath.node.openingElement.attributes.forEach((attr) => {
if (attr.name?.name === 'slotProps') {
hasNode = true;
assignObject(j, {
target: attr,
key: 'img',
expression: removed[0].value.expression,
});
}
});
if (!hasNode) {
appendAttribute(j, {
target: elementPath.node,
attributeName: 'slotProps',
expression: j.objectExpression([
j.objectProperty(j.identifier('img'), removed[0].value.expression),
]),
});
}
}
});

root.find(j.ObjectProperty, { key: { name: 'imgProps' } }).forEach((path) => {
if (path.parent?.parent?.parent?.parent?.node.key?.name === 'MuiAvatar') {
path.replace(
j.property(
'init',
j.identifier('slotProps'),
j.objectExpression([j.objectProperty(j.identifier('img'), path.node.value)]),
),
);
}
movePropIntoSlotProps(j, {
root,
componentName: 'Avatar',
propName: 'imgProps',
slotName: 'img',
});

return root.toSource(printOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ import { Avatar as MyAvatar } from '@mui/material';
onLoad: () => {},
}}
/>;
<MyAvatar
imgProps={{
onLoad: () => {},
}}
slotProps={{
img: {
onError: () => {},
},
}}
/>;

// should skip non MUI components
<NonMuiAvatar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ import { Avatar as MyAvatar } from '@mui/material';
}
}}
/>;
<MyAvatar
slotProps={{
img: {
...{
onLoad: () => {},
},

...{
onError: () => {},
}
},
}} />;

// should skip non MUI components
<NonMuiAvatar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,18 @@ fn({
},
},
});

fn({
MuiAvatar: {
defaultProps: {
imgProps: {
onLoad: () => {},
},
slotProps: {
img: {
onError: () => {},
},
},
},
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@ fn({
onError: () => {},
onLoad: () => {},
}
},
},
},
});

fn({
MuiAvatar: {
defaultProps: {
slotProps: {
img: {
...{
onLoad: () => {},
},

...{
onError: () => {},
}
},
}
},
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import findComponentJSX from '../../util/findComponentJSX';
import assignObject from '../../util/assignObject';
import appendAttribute from '../../util/appendAttribute';
import movePropIntoSlots from '../utils/movePropIntoSlots';

/**
* @param {import('jscodeshift').FileInfo} file
Expand All @@ -11,73 +9,11 @@ export default function transformer(file, api, options) {
const root = j(file.source);
const printOptions = options.printOptions;

findComponentJSX(j, { root, componentName: 'Backdrop' }, (elementPath) => {
const index = elementPath.node.openingElement.attributes.findIndex(
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'TransitionComponent',
);

if (index !== -1) {
const removed = elementPath.node.openingElement.attributes.splice(index, 1);
let hasNode = false;
elementPath.node.openingElement.attributes.forEach((attr) => {
if (attr.name?.name === 'slots') {
hasNode = true;
assignObject(j, {
target: attr,
key: 'transition',
expression: removed[0].value.expression,
});
}
});

if (!hasNode) {
appendAttribute(j, {
target: elementPath.node,
attributeName: 'slots',
expression: j.objectExpression([
j.objectProperty(j.identifier('transition'), removed[0].value.expression),
]),
});
}
}
});

root.find(j.ObjectProperty, { key: { name: 'TransitionComponent' } }).forEach((path) => {
if (path.parent?.parent?.parent?.parent?.node.key?.name === 'MuiBackdrop') {
const { properties: defaultPropsProperties } = path.parent.value;

const existingSlots = defaultPropsProperties.find((prop) => prop.key.name === 'slots');
const slots = existingSlots
? existingSlots.value.properties.reduce((acc, prop) => {
return { ...acc, [prop.key.name]: prop.value };
}, {})
: {};

const transitionComponent =
defaultPropsProperties.find((prop) => prop.key.name === 'TransitionComponent') ?? {};

const updatedSlots = j.objectExpression(
Object.entries({
transition: transitionComponent?.value,
...slots,
}).map(([slot, value]) => {
return j.objectProperty(j.identifier(slot), value);
}),
);

if (existingSlots) {
existingSlots.value = updatedSlots;
path.prune();
} else {
path.replace(
j.property(
'init',
j.identifier('slots'),
j.objectExpression([j.objectProperty(j.identifier('transition'), path.node.value)]),
),
);
}
}
movePropIntoSlots(j, {
root,
componentName: 'Backdrop',
propName: 'TransitionComponent',
slotName: 'transition',
});

return root.toSource(printOptions);
Expand Down
Loading

0 comments on commit f837591

Please sign in to comment.