-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
[charts] Remove colors
prop from SparkLineChart
.
#16494
base: master
Are you sure you want to change the base?
Changes from all commits
2416f74
f5f7fe9
5666963
9ec017d
59c2b49
237df3b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* eslint-disable no-restricted-imports, @typescript-eslint/no-shadow */ | ||
import * as React from 'react'; | ||
import { SparkLineChart } from '@mui/x-charts'; | ||
|
||
const data = [1, 2]; | ||
|
||
function Chart() { | ||
const fn = (mode) => (mode === 'light' ? ['black'] : ['white']); | ||
|
||
// prettier-ignore | ||
return ( | ||
<React.Fragment> | ||
<SparkLineChart data={data} colors={['red']} /> | ||
<SparkLineChart data={data} colors={fn} /> | ||
<SparkLineChart data={data} colors={(mode) => (mode === 'light' ? ['black'] : ['white'])} /> | ||
</React.Fragment> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* eslint-disable no-restricted-imports, @typescript-eslint/no-shadow */ | ||
import * as React from 'react'; | ||
import { SparkLineChart } from '@mui/x-charts'; | ||
|
||
const data = [1, 2]; | ||
|
||
function Chart() { | ||
const fn = (mode) => (mode === 'light' ? ['black'] : ['white']); | ||
|
||
// prettier-ignore | ||
return ( | ||
(<React.Fragment> | ||
<SparkLineChart data={data} color={['red']?.[0]} /> | ||
<SparkLineChart data={data} color={typeof fn === "function" ? mode => fn(mode)?.[0] : fn} /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if this is a valid approach. This introduces a slight runtime performance hit because, when codemodding, we can't guarantee whether If you think this or another example are too complex, I can just remove this and leave this as an unhandled case. |
||
<SparkLineChart data={data} color={mode => (mode => (mode === 'light' ? ['black'] : ['white']))(mode)?.[0]} /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This might seem a bit confusing, but what I'm doing is: Given an arrow function declaration We need the optional chaining operator because |
||
</React.Fragment>) | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { JsCodeShiftAPI, JsCodeShiftFileInfo } from '../../../types'; | ||
/** | ||
* @param {import('jscodeshift').FileInfo} file | ||
* @param {import('jscodeshift').API} api | ||
*/ | ||
export default function transformer(file: JsCodeShiftFileInfo, api: JsCodeShiftAPI, options: any) { | ||
const j = api.jscodeshift; | ||
|
||
const printOptions = options.printOptions; | ||
|
||
const root = j(file.source); | ||
const componentNames = ['SparkLineChart']; | ||
const props = { colors: 'color' }; | ||
|
||
const colorAttributes = root | ||
.find(j.JSXElement) | ||
.filter((path) => { | ||
return componentNames.includes((path.value.openingElement.name as any).name); | ||
}) | ||
.find(j.JSXAttribute) | ||
.filter((attribute) => Object.keys(props).includes(attribute.node.name.name as string)); | ||
|
||
return colorAttributes | ||
.forEach((attribute) => { | ||
if (attribute.node.value?.type !== 'JSXExpressionContainer') { | ||
return; | ||
} | ||
|
||
const colorsAttributeExpression = attribute.node.value.expression; | ||
|
||
let colorAttributeExpression; | ||
|
||
if (colorsAttributeExpression.type === 'ArrayExpression') { | ||
colorAttributeExpression = j.chainExpression( | ||
j.optionalMemberExpression(colorsAttributeExpression, j.literal(0)), | ||
); | ||
} else if (colorsAttributeExpression.type === 'Identifier') { | ||
colorAttributeExpression = j.conditionalExpression( | ||
j.binaryExpression( | ||
'===', | ||
j.unaryExpression('typeof', colorsAttributeExpression), | ||
j.literal('function'), | ||
), | ||
j.arrowFunctionExpression( | ||
[j.identifier('mode')], | ||
j.chainExpression( | ||
j.optionalMemberExpression( | ||
j.callExpression(colorsAttributeExpression, [j.identifier('mode')]), | ||
j.literal(0), | ||
), | ||
), | ||
), | ||
colorsAttributeExpression, | ||
); | ||
} else if (colorsAttributeExpression.type === 'ArrowFunctionExpression') { | ||
colorAttributeExpression = j.arrowFunctionExpression( | ||
[j.identifier('mode')], | ||
j.chainExpression( | ||
j.optionalMemberExpression( | ||
j.callExpression(colorsAttributeExpression, [j.identifier('mode')]), | ||
j.literal(0), | ||
), | ||
), | ||
); | ||
} else { | ||
// Don't know how to handle this case | ||
} | ||
|
||
// Only apply transformation if we know how to handle it | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any best practice for letting the user know where we caught an unhandled case? I know we aren't covering 100% of the cases, and some are easy to detect, but hard to fix. It would be nice if we could let the user know which ones have been detected to guide them towards where they need to do a manual fix. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we currently notify unhandled cases There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can propose that though 👍 |
||
if (colorAttributeExpression) { | ||
j(attribute).replaceWith( | ||
j.jsxAttribute( | ||
j.jsxIdentifier(props[attribute.node.name.name as string]), | ||
j.jsxExpressionContainer(colorAttributeExpression), | ||
), | ||
); | ||
} | ||
}) | ||
.toSource(printOptions); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import path from 'path'; | ||
import { expect } from 'chai'; | ||
import jscodeshift from 'jscodeshift'; | ||
import transform from '.'; | ||
import readFile from '../../../util/readFile'; | ||
|
||
function read(fileName) { | ||
return readFile(path.join(__dirname, fileName)); | ||
} | ||
|
||
describe('v8.0.0/charts', () => { | ||
describe('rename-sparkline-colors-to-color', () => { | ||
it('transforms code as needed', () => { | ||
const actual = transform( | ||
{ | ||
source: read('./actual.spec.tsx'), | ||
path: require.resolve('./actual.spec.tsx'), | ||
}, | ||
{ jscodeshift: jscodeshift.withParser('tsx') }, | ||
{}, | ||
); | ||
|
||
const expected = read('./expected.spec.tsx'); | ||
expect(actual).to.equal(expected, 'The transformed version should be correct'); | ||
}); | ||
|
||
it('should be idempotent for expression', () => { | ||
const actual = transform( | ||
{ | ||
source: read('./expected.spec.tsx'), | ||
path: require.resolve('./expected.spec.tsx'), | ||
}, | ||
{ jscodeshift: jscodeshift.withParser('tsx') }, | ||
{}, | ||
); | ||
|
||
const expected = read('./expected.spec.tsx'); | ||
expect(actual).to.equal(expected, 'The transformed version should be correct'); | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I followed a "better safe than sorry" approach here. Adding the optional chain operator might save us from some crashes in edge cases. Happy to remove it if you think that's too much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what will happen to
var
whenvar=['blue']
?