Skip to content

Commit

Permalink
[material-ui][Divider] Add codemod for light prop removal (#40947)
Browse files Browse the repository at this point in the history
  • Loading branch information
sai6855 committed Feb 7, 2024
1 parent bc5b480 commit e118cfe
Show file tree
Hide file tree
Showing 12 changed files with 316 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,16 @@ The Accordion's `TransitionProps` was deprecated in favor of `slotProps.transiti
+ slotProps={{ transition: { unmountOnExit: true } }}
/>
```

## Divider

### light

The Divider's `light` prop was deprecated, Use `sx={{ opacity : "0.6" }}` (or any opacity). ([Codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#divider-props)):

```diff
<Divider
- light
+ sx={{ opacity : "0.6" }}
/>
```
2 changes: 1 addition & 1 deletion docs/pages/material-ui/api/divider.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"type": { "name": "bool" },
"default": "false",
"deprecated": true,
"deprecationInfo": "Use &lt;Divider sx={{ bgcolor: &#39;#eee&#39; }} /&gt; (or any color) instead."
"deprecationInfo": "Use &lt;Divider sx={{ opacity: 0.6 }} /&gt; (or any opacity or color) instead. <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">How to migrate</a>"
},
"orientation": {
"type": { "name": "enum", "description": "'horizontal'<br>&#124;&nbsp;'vertical'" },
Expand Down
13 changes: 13 additions & 0 deletions packages/mui-codemod/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,19 @@ A combination of all deprecations.
npx @mui/codemod@latest deprecations/accordion-props <path>
```

#### `divider-props`

```diff
<Divider
- light
+ sx={{opacity: "0.6"}}
/>
```

```bash
npx @mui/codemod@latest deprecations/divider-props <path>
```

### v5.0.0

#### `base-use-named-exports`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import appendAttribute from '../../util/appendAttribute';
import assignObject from '../../util/assignObject';
import findComponentJSX from '../../util/findComponentJSX';

/**
* @param {import('jscodeshift').FileInfo} file
* @param {import('jscodeshift').API} api
*/
export default function transformer(file, api, options) {
const j = api.jscodeshift;
const root = j(file.source);
const printOptions = options.printOptions;

findComponentJSX(j, { root, componentName: 'Divider' }, (elementPath) => {
elementPath.node.openingElement.attributes = elementPath.node.openingElement.attributes.filter(
(attr) => {
if (attr.type === 'JSXAttribute' && attr.name.name === 'light') {
return false;
}
return true;
},
);

const sxIndex = elementPath.node.openingElement.attributes.findIndex(
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'sx',
);
if (sxIndex === -1) {
appendAttribute(j, {
target: elementPath.node,
attributeName: 'sx',
expression: j.objectExpression([
j.objectProperty(j.identifier('opacity'), j.literal('0.6')),
]),
});
} else {
const opacityIndex = elementPath.node.openingElement.attributes[
sxIndex
].value.expression.properties.findIndex((key) => key.key.name === 'opacity');

if (opacityIndex === -1) {
assignObject(j, {
target: elementPath.node.openingElement.attributes[sxIndex],
key: 'opacity',
expression: j.literal('0.6'),
});
}
}
});

root.find(j.ObjectProperty, { key: { name: 'MuiDivider' } }).forEach((path) => {
const defaultPropsObject = path.value.value.properties.find(
(key) => key.key.name === 'defaultProps',
);

defaultPropsObject.value.properties = defaultPropsObject.value.properties.filter(
(prop) => !['light'].includes(prop?.key?.name),
);

const sxIndex = defaultPropsObject.value.properties.findIndex((prop) => prop.key.name === 'sx');

if (sxIndex === -1) {
defaultPropsObject.value.properties.push(
j.objectProperty(
j.identifier('sx'),
j.objectExpression([j.objectProperty(j.identifier('opacity'), j.literal('0.6'))]),
),
);
} else {
const opacityIndex = defaultPropsObject.value.properties[sxIndex].value.properties.findIndex(
(key) => key.key.name === 'opacity',
);

if (opacityIndex === -1) {
defaultPropsObject.value.properties[sxIndex].value.properties.push(
j.objectProperty(j.identifier('opacity'), j.literal('0.6')),
);
}
}
});

return root.toSource(printOptions);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import path from 'path';
import { expect } from 'chai';
import { jscodeshift } from '../../../testUtils';
import transform from './divider-props';
import readFile from '../../util/readFile';

function read(fileName) {
return readFile(path.join(__dirname, fileName));
}

describe('@mui/codemod', () => {
describe('deprecations', () => {
describe('divider-props', () => {
it('transforms props as needed', () => {
const actual = transform({ source: read('./test-cases/actual.js') }, { jscodeshift }, {});

const expected = read('./test-cases/expected.js');
expect(actual).to.equal(expected, 'The transformed version should be correct');
});

it('should be idempotent', () => {
const actual = transform({ source: read('./test-cases/expected.js') }, { jscodeshift }, {});

const expected = read('./test-cases/expected.js');
expect(actual).to.equal(expected, 'The transformed version should be correct');
});

it('actual.js should not be equal to expected.js', () => {
const actual = read('./test-cases/actual.js');
const expected = read('./test-cases/expected.js');
expect(actual).to.not.equal(expected);
});
});

describe('[theme] divider-props', () => {
it('transforms props as needed', () => {
const actual = transform(
{ source: read('./test-cases/theme.actual.js') },
{ jscodeshift },
{},
);

const expected = read('./test-cases/theme.expected.js');
expect(actual).to.equal(expected, 'The transformed version should be correct');
});

it('should be idempotent', () => {
const actual = transform(
{ source: read('./test-cases/theme.expected.js') },
{ jscodeshift },
{},
);

const expected = read('./test-cases/theme.expected.js');
expect(actual).to.equal(expected, 'The transformed version should be correct');
});

it('theme.actual.js should not be equal to theme.expected.js', () => {
const actual = read('./test-cases/theme.actual.js');
const expected = read('./test-cases/theme.expected.js');
expect(actual).to.not.equal(expected);
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './divider-props';
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Divider from '@mui/material/Divider';
import { Divider as MyDivider } from '@mui/material';

<Divider light className="test" />;
<MyDivider light className="test" />;
<Divider light={false} className="test" />;
<MyDivider light={false} className="test" />;
<Divider light={light} className="test" />;
<MyDivider light={light} className="test" />;
<Divider light sx={{ opacity: '0.7' }} />;
<MyDivider light sx={{ bgcolor: 'black' }} />;
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Divider from '@mui/material/Divider';
import { Divider as MyDivider } from '@mui/material';

<Divider className="test" sx={{
opacity: "0.6"
}} />;
<MyDivider className="test" sx={{
opacity: "0.6"
}} />;
<Divider className="test" sx={{
opacity: "0.6"
}} />;
<MyDivider className="test" sx={{
opacity: "0.6"
}} />;
<Divider className="test" sx={{
opacity: "0.6"
}} />;
<MyDivider className="test" sx={{
opacity: "0.6"
}} />;
<Divider sx={{ opacity: '0.7' }} />;
<MyDivider
sx={{
bgcolor: 'black',
opacity: "0.6"
}} />;
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
fn({
MuiDivider: {
defaultProps: {
light: true,
},
},
});
fn({
MuiDivider: {
defaultProps: {
light: true,
className: 'my-class',
},
},
});
fn({
MuiDivider: {
defaultProps: {
light,
className: 'my-class',
},
},
});

fn({
MuiDivider: {
defaultProps: {
light,
className: 'my-class',
sx: {
opacity: '0.7',
},
},
},
});

fn({
MuiDivider: {
defaultProps: {
light,
className: 'my-class',
sx: {
bgcolor: 'black',
},
},
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
fn({
MuiDivider: {
defaultProps: {
sx: {
opacity: "0.6"
},
},
},
});
fn({
MuiDivider: {
defaultProps: {
className: 'my-class',
sx: {
opacity: "0.6"
},
},
},
});
fn({
MuiDivider: {
defaultProps: {
className: 'my-class',
sx: {
opacity: "0.6"
},
},
},
});

fn({
MuiDivider: {
defaultProps: {
className: 'my-class',

sx: {
opacity: '0.7',
}
},
},
});

fn({
MuiDivider: {
defaultProps: {
className: 'my-class',

sx: {
bgcolor: 'black',
opacity: "0.6"
}
},
},
});
2 changes: 1 addition & 1 deletion packages/mui-material/src/Divider/Divider.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export interface DividerOwnProps {
/**
* If `true`, the divider will have a lighter color.
* @default false
* @deprecated Use <Divider sx={{ bgcolor: '#eee' }} /> (or any color) instead.
* @deprecated Use <Divider sx={{ opacity: 0.6 }} /> (or any opacity or color) instead. [How to migrate](/material-ui/migration/migrating-from-deprecated-apis/)
*/
light?: boolean;
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/mui-material/src/Divider/Divider.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ Divider.propTypes /* remove-proptypes */ = {
/**
* If `true`, the divider will have a lighter color.
* @default false
* @deprecated Use <Divider sx={{ bgcolor: '#eee' }} /> (or any color) instead.
* @deprecated Use <Divider sx={{ opacity: 0.6 }} /> (or any opacity or color) instead. [How to migrate](/material-ui/migration/migrating-from-deprecated-apis/)
*/
light: PropTypes.bool,
/**
Expand Down

0 comments on commit e118cfe

Please sign in to comment.