diff --git a/packages/mui-codemod/src/v6.0.0/sx-prop/sx-v6.js b/packages/mui-codemod/src/v6.0.0/sx-prop/sx-v6.js index 9d5cdc4ad2afbe..585f3309541f07 100644 --- a/packages/mui-codemod/src/v6.0.0/sx-prop/sx-v6.js +++ b/packages/mui-codemod/src/v6.0.0/sx-prop/sx-v6.js @@ -339,15 +339,46 @@ export default function sxV6(file, api, options) { } } if (data.node.argument.type === 'ConditionalExpression') { - recurseObjectExpression({ - ...data, - node: data.node.argument, - parentNode: data.node, - }); - if (data.deleteSelf) { - data.deleteSelf(); - } else { - removeProperty(data.parentNode, data.node); + const isSxSpread = + (data.node.argument.consequent.type === 'Identifier' && + data.node.argument.consequent.name === 'sx') || + (data.node.argument.alternate.type === 'Identifier' && + data.node.argument.alternate.name === 'sx'); + + if (!isSxSpread) { + recurseObjectExpression({ + ...data, + node: data.node.argument, + parentNode: data.node, + }); + wrapSxInArray(data.node.argument); + if (data.deleteSelf) { + data.deleteSelf(); + } else { + removeProperty(data.parentNode, data.node); + } + } + } + if (data.node.argument.type === 'CallExpression') { + if ( + getObjectKey(data.node.argument.callee)?.name === 'theme' && + data.node.argument.callee.property?.name?.startsWith('apply') + ) { + const objIndex = data.node.argument.arguments.findIndex( + (arg) => arg.type === 'ObjectExpression', + ); + recurseObjectExpression({ + ...data, + node: data.node.argument.arguments[objIndex], + buildStyle: (styleExpression) => { + const newArguments = [...data.node.argument.arguments]; + newArguments[objIndex] = styleExpression; + return j.arrowFunctionExpression([j.identifier('theme')], { + ...data.node.argument, + arguments: newArguments, + }); + }, + }); } } } diff --git a/packages/mui-codemod/src/v6.0.0/sx-prop/sx-v6.test.js b/packages/mui-codemod/src/v6.0.0/sx-prop/sx-v6.test.js index aeb78bc798f112..3dd70803719687 100644 --- a/packages/mui-codemod/src/v6.0.0/sx-prop/sx-v6.test.js +++ b/packages/mui-codemod/src/v6.0.0/sx-prop/sx-v6.test.js @@ -129,5 +129,53 @@ describe('@mui/codemod', () => { expect(actual).to.equal(expected, 'The transformed version should be correct'); }); }); + + describe('conditional sx-v6', () => { + it('transforms props as needed', () => { + const actual = transform( + { source: read('./test-cases/sx-condition.actual.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/sx-condition.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read('./test-cases/sx-condition.expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/sx-condition.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); + + describe('applyStyles sx-v6', () => { + it('transforms props as needed', () => { + const actual = transform( + { source: read('./test-cases/sx-applyStyles.actual.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/sx-applyStyles.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read('./test-cases/sx-applyStyles.expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/sx-applyStyles.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + }); }); }); diff --git a/packages/mui-codemod/src/v6.0.0/sx-prop/test-cases/sx-applyStyles.actual.js b/packages/mui-codemod/src/v6.0.0/sx-prop/test-cases/sx-applyStyles.actual.js new file mode 100644 index 00000000000000..d7696ea30630ee --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/sx-prop/test-cases/sx-applyStyles.actual.js @@ -0,0 +1,90 @@ + { + if (ref.current) { + ref.current.scrollIntoView({ block: 'nearest' }); + } + if (props.onClick) { + props.onClick(event); + } + }} + onFocusVisible={(event) => { + if (ref.current) { + ref.current.scrollIntoView({ block: 'nearest' }); + } + if (props.onFocusVisible) { + props.onFocusVisible(event); + } + }} + sx={[ + (theme) => ({ + justifyContent: 'flex-start', + textAlign: 'left', + alignItems: 'center', + borderRadius: 1, + height: '100%', + border: '1px solid transparent', + transitionProperty: 'all', + transitionDuration: '150ms', + // color: 'primary.300', + overflow: 'auto', + ...((!disableBorder || selected) && { + borderColor: 'grey.100', + }), + ...(selected && { + bgcolor: `${alpha(theme.palette.primary[50], 0.5)}`, + borderColor: 'primary.300', + boxShadow: `0px 1px 4px ${theme.palette.primary[200]}, inset 0px 2px 4px ${alpha( + theme.palette.primary[100], + 0.5, + )}`, + // color: 'primary.500', + }), + ...(!selected && { + '&:hover, &:focus': { + bgcolor: 'primary.50', + borderColor: 'primary.100', + '@media (hover: none)': { + bgcolor: 'transparent', + }, + }, + }), + ...theme.applyDarkStyles({ + color: 'primary.800', + ...((!disableBorder || selected) && { + borderColor: `${alpha(theme.palette.primaryDark[600], 0.3)}`, + }), + ...(!selected && { + '&:hover, &:focus': { + bgcolor: `${alpha(theme.palette.primary[800], 0.1)}`, + borderColor: `${alpha(theme.palette.primary[500], 0.3)}`, + '@media (hover: none)': { + bgcolor: 'transparent', + }, + }, + }), + ...(selected && { + bgcolor: `${alpha(theme.palette.primary[800], 0.3)}`, + borderColor: 'primary.700', + // color: 'primary.300', + boxShadow: `0px 1px 4px ${ + (theme.vars || theme).palette.primary[900] + }, inset 0px 2px 4px ${(theme.vars || theme).palette.primaryDark[800]}`, + }), + }), + ...theme.applyStyles('light', { + color: 'primary.500', + ...((!disableBorder || selected) && { + borderColor: `${alpha(theme.palette.primary[300], 0.3)}`, + }), + }), + '&.Mui-disabled': { + opacity: 0.4, + }, + }), + ...(Array.isArray(sx) ? sx : [sx]), + ]} +/>; diff --git a/packages/mui-codemod/src/v6.0.0/sx-prop/test-cases/sx-applyStyles.expected.js b/packages/mui-codemod/src/v6.0.0/sx-prop/test-cases/sx-applyStyles.expected.js new file mode 100644 index 00000000000000..2d52b73a15f86d --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/sx-prop/test-cases/sx-applyStyles.expected.js @@ -0,0 +1,80 @@ + { + if (ref.current) { + ref.current.scrollIntoView({ block: 'nearest' }); + } + if (props.onClick) { + props.onClick(event); + } + }} + onFocusVisible={(event) => { + if (ref.current) { + ref.current.scrollIntoView({ block: 'nearest' }); + } + if (props.onFocusVisible) { + props.onFocusVisible(event); + } + }} + sx={[(theme) => ({ + justifyContent: 'flex-start', + textAlign: 'left', + alignItems: 'center', + borderRadius: 1, + height: '100%', + border: '1px solid transparent', + transitionProperty: 'all', + transitionDuration: '150ms', + // color: 'primary.300', + overflow: 'auto', + ...theme.applyDarkStyles({ + color: 'primary.800' + }), + ...theme.applyStyles('light', { + color: 'primary.500' + }), + '&.Mui-disabled': { + opacity: 0.4, + } + }), (!disableBorder || selected) && { + borderColor: 'grey.100', + }, selected && (theme => ({ + bgcolor: `${alpha(theme.palette.primary[50], 0.5)}`, + borderColor: 'primary.300', + // color: 'primary.500', + boxShadow: `0px 1px 4px ${theme.palette.primary[200]}, inset 0px 2px 4px ${alpha( + theme.palette.primary[100], + 0.5, + )}` + })), !selected && { + '&:hover, &:focus': { + bgcolor: 'primary.50', + borderColor: 'primary.100', + '@media (hover: none)': { + bgcolor: 'transparent', + }, + }, + }, (!disableBorder || selected) && (theme => theme.applyDarkStyles({ + borderColor: `${alpha(theme.palette.primaryDark[600], 0.3)}`, + })), !selected && (theme => theme.applyDarkStyles({ + '&:hover, &:focus': { + bgcolor: `${alpha(theme.palette.primary[800], 0.1)}`, + borderColor: `${alpha(theme.palette.primary[500], 0.3)}`, + '@media (hover: none)': { + bgcolor: 'transparent', + }, + }, + })), selected && (theme => theme.applyDarkStyles({ + bgcolor: `${alpha(theme.palette.primary[800], 0.3)}`, + borderColor: 'primary.700', + // color: 'primary.300', + boxShadow: `0px 1px 4px ${ + (theme.vars || theme).palette.primary[900] + }, inset 0px 2px 4px ${(theme.vars || theme).palette.primaryDark[800]}`, + })), (!disableBorder || selected) && (theme => theme.applyStyles('light', { + borderColor: `${alpha(theme.palette.primary[300], 0.3)}`, + })), ...(Array.isArray(sx) ? sx : [sx])]} +/>; diff --git a/packages/mui-codemod/src/v6.0.0/sx-prop/test-cases/sx-condition.actual.js b/packages/mui-codemod/src/v6.0.0/sx-prop/test-cases/sx-condition.actual.js new file mode 100644 index 00000000000000..bf73fee6620849 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/sx-prop/test-cases/sx-condition.actual.js @@ -0,0 +1,98 @@ + { + ev.preventDefault(); + navigate(href); + }} +> + + + + {productOffer && productOffer.ui?.itemCard && ( + + {productOffer.offerText} + + )} + + + +; diff --git a/packages/mui-codemod/src/v6.0.0/sx-prop/test-cases/sx-condition.expected.js b/packages/mui-codemod/src/v6.0.0/sx-prop/test-cases/sx-condition.expected.js new file mode 100644 index 00000000000000..2a6689cc993f00 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/sx-prop/test-cases/sx-condition.expected.js @@ -0,0 +1,90 @@ + { + ev.preventDefault(); + navigate(href); + }} +> + + + + {productOffer && productOffer.ui?.itemCard && ( + + {productOffer.offerText} + + )} + + + +;