in packages/eslint-plugin-baseui/src/deprecated-component-api.js [175:443]
JSXIdentifier(node) {
// =======
// Helpers
// =======
// isProp
// Check if identifier is a prop with matching "name" and is used with
// "component".
// Ex: isProp("foo", "Boo") with <Boo foo={} /> => true
function isProp(name, component) {
return (
node.name === name &&
context
.getAncestors()
.some(
(ancestor) =>
ancestor.type === 'JSXOpeningElement' && ancestor.name.name === component
)
);
}
// isComponent
// Check if identifier is a component.
// Ex: isComponent() with <Boo foo={} /> => true
function isComponent() {
return (
node.parent.type === 'JSXOpeningElement' || node.parent.type === 'JSXClosingElement'
);
}
// ================
// Deprecated Props
// ================
// renderPanelContent
// Ex: <Accordion renderPanelContent />
// Replacement: renderAll
if (importState.Accordion && isProp('renderPanelContent', importState.Accordion)) {
context.report({
node,
messageId: MESSAGES.replace.id,
data: {
old: 'renderPanelContent',
new: 'renderAll',
},
fix: function (fixer) {
return fixer.replaceText(node, 'renderAll');
},
});
return;
}
// autofocus
// Ex: <Modal autofocus />
// Replacement: autoFocus
if (importState.Modal && isProp('autofocus', importState.Modal)) {
context.report({
node: node,
messageId: MESSAGES.replace.id,
data: {
old: `autofocus`,
new: `autoFocus`,
},
fix: function (fixer) {
return fixer.replaceText(node, 'autoFocus');
},
});
return;
}
// ======================
// Deprecated Prop Values
// ======================
// checkmarkType
// Ex: <Checkbox checkmarkType="toggle" />
// Ex: <Checkbox checkmarkType={STYLE_TYPE.toggle} />
// Replacement: toggle_round
if (importState.Checkbox && isProp('checkmarkType', importState.Checkbox)) {
// The value can be a constant or a string literal.
// We need to handle each a little differently.
if (node.parent.value.type === 'Literal' && node.parent.value.value === 'toggle') {
// Ex: <Checkmark checkmarkType="toggle" />
context.report({
node: node.parent.value,
messageId: MESSAGES.replace.id,
data: {
old: `toggle`,
new: `toggle_round`,
},
fix: function (fixer) {
return fixer.replaceText(node.parent.value, `"toggle_round"`);
},
});
} else if (
node.parent.value.type === 'JSXExpressionContainer' &&
node.parent.value.expression.type === 'MemberExpression' &&
node.parent.value.expression.object.name === 'STYLE_TYPE' &&
node.parent.value.expression.property.name === 'toggle'
) {
// Ex: <Checkmark checkmarkType={STYLE_TYPE.toggle} />
context.report({
node: node.parent.value.expression.property,
messageId: MESSAGES.replace.id,
data: {
old: `STYLE_TYPE.toggle`,
new: `STYLE_TYPE.toggle_round`,
},
fix: function (fixer) {
return fixer.replaceText(node.parent.value.expression.property, 'toggle_round');
},
});
return;
}
}
// Checkbox - isError
// Ex: <Checkbox isError />
// Replacement: error
if (importState.Checkbox && isProp('isError', importState.Checkbox)) {
context.report({
node: node,
messageId: MESSAGES.replace.id,
data: {
old: `isError`,
new: `error`,
},
fix: function (fixer) {
return fixer.replaceText(node, 'error');
},
});
return;
}
// Radio - isError
// Ex: <Radio isError />
// Replacement: error
if (importState.Radio && isProp('isError', importState.Radio)) {
context.report({
node: node,
messageId: MESSAGES.replace.id,
data: {
old: `isError`,
new: `error`,
},
fix: function (fixer) {
return fixer.replaceText(node, 'error');
},
});
return;
}
// RadioGroup - isError
// Ex: <RadioGroup isError />
// Replacement: error
if (importState.RadioGroup && isProp('isError', importState.RadioGroup)) {
context.report({
node: node,
messageId: MESSAGES.replace.id,
data: {
old: `isError`,
new: `error`,
},
fix: function (fixer) {
return fixer.replaceText(node, 'error');
},
});
return;
}
// kind
// Ex: <Button kind="minimal" />
// Ex: <Button kind={KIND.minimal} />
// Replacement: tertiary
if (importState.Button && isProp('kind', importState.Button)) {
// The value can be a constant or a string literal.
// We need to handle each a little differently.
if (node.parent.value.type === 'Literal' && node.parent.value.value === 'minimal') {
// Ex: <Button kind="minimal" />
context.report({
node: node.parent.value,
messageId: MESSAGES.buttonKindMinimal.id,
});
return;
} else if (
node.parent.value.type === 'JSXExpressionContainer' &&
node.parent.value.expression.type === 'MemberExpression' &&
node.parent.value.expression.object.name === 'KIND' &&
node.parent.value.expression.property.name === 'minimal'
) {
// Ex: <Button kind={KIND.minimal} />
context.report({
node: node.parent.value.expression.property,
messageId: MESSAGES.buttonKindMinimal.id,
});
return;
}
}
// ====================
// Deprecated overrides
// ====================
// Backdrop
// Ex: <Modal overrides={{ Backdrop: {}}} />
// Replacement: DialogContainer
if (importState.Modal && isProp('overrides', importState.Modal)) {
const property = getOverrideIfExists('Backdrop', node);
if (property) {
context.report({
node: property,
messageId: MESSAGES.modalBackdrop.id,
});
return;
}
}
// RadioGroup - All overrides are deprecated except for RadioGroupRoot
// Ex: <RadioGroup overrides={{ RadioMarkInner: {}}} />
// Ex: <RadioGroup overrides={{ Description: {}}} />
// Ex: <RadioGroup overrides={{ Root: {}}} />
// Replacement: None
if (importState.RadioGroup && isProp('overrides', importState.RadioGroup)) {
const properties = [
'Root',
'Input',
'Label',
'Description',
'RadioMarkInner',
'RadioMarkOuter',
];
properties.map((val) => {
const property = getOverrideIfExists(val, node);
if (property) {
context.report({
node: property,
messageId: MESSAGES.radioGroupOverrides.id,
});
}
});
}
// =====================
// Deprecated Components
// =====================
// See @ImportSpecifier function for how this importState.Caption1
// stuff works.
// Replace deprecated component usage.
// Caption1
// Ex: <Caption1 />
// Replacement: ParagraphXSmall
if (Object.prototype.hasOwnProperty.call(identifiersToRename, node.name) && isComponent()) {
const oldName = node.name;
const newName = identifiersToRename[node.name];
context.report({
node,
messageId: MESSAGES.replace.id,
data: {
old: oldName,
new: newName,
},
fix: function (fixer) {
return [fixer.replaceText(node, newName)];
},
});
}
},