You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
3.3 KiB

2 years ago
"use strict";
exports.__esModule = true;
exports.default = void 0;
const elementToComponent = {
svg: 'Svg',
circle: 'Circle',
clipPath: 'ClipPath',
ellipse: 'Ellipse',
g: 'G',
linearGradient: 'LinearGradient',
radialGradient: 'RadialGradient',
line: 'Line',
path: 'Path',
pattern: 'Pattern',
polygon: 'Polygon',
polyline: 'Polyline',
rect: 'Rect',
symbol: 'Symbol',
text: 'Text',
textPath: 'TextPath',
tspan: 'TSpan',
use: 'Use',
defs: 'Defs',
stop: 'Stop',
mask: 'Mask',
image: 'Image',
foreignObject: 'ForeignObject'
};
const expoPrefix = (component, expo) => {
// Prefix with 'Svg.' in the case we're transforming for Expo
if (!expo) {
return component;
}
return (component !== 'Svg' ? 'Svg.' : '') + component;
};
const plugin = ({
types: t
}, {
expo
}) => {
function replaceElement(path, state) {
const {
name
} = path.node.openingElement.name; // Replace element by react-native-svg components
const component = elementToComponent[name];
if (component) {
const prefixedComponent = expoPrefix(component, expo);
const openingElementName = path.get('openingElement.name');
openingElementName.replaceWith(t.jsxIdentifier(prefixedComponent));
if (path.has('closingElement')) {
const closingElementName = path.get('closingElement.name');
closingElementName.replaceWith(t.jsxIdentifier(prefixedComponent));
}
state.replacedComponents.add(prefixedComponent);
return;
} // Remove element if not supported
state.unsupportedComponents.add(name);
path.remove();
}
const svgElementVisitor = {
JSXElement(path, state) {
if (!path.get('openingElement.name').isJSXIdentifier({
name: 'svg'
})) {
return;
}
replaceElement(path, state);
path.traverse(jsxElementVisitor, state);
}
};
const jsxElementVisitor = {
JSXElement(path, state) {
replaceElement(path, state);
}
};
const importDeclarationVisitor = {
ImportDeclaration(path, state) {
if (path.get('source').isStringLiteral({
value: 'react-native-svg'
})) {
state.replacedComponents.forEach(component => {
if (path.get('specifiers').some(specifier => specifier.get('local').isIdentifier({
name: component
}))) {
return;
}
path.pushContainer('specifiers', t.importSpecifier(t.identifier(component), t.identifier(component)));
});
} else if (path.get('source').isStringLiteral({
value: 'expo'
})) {
path.pushContainer('specifiers', t.importSpecifier(t.identifier('Svg'), t.identifier('Svg')));
} else {
return;
}
if (state.unsupportedComponents.size && !path.has('trailingComments')) {
const componentList = [...state.unsupportedComponents].join(', ');
path.addComment('trailing', ` SVGR has dropped some elements not supported by react-native-svg: ${componentList} `);
}
}
};
return {
visitor: {
Program(path, state) {
state.replacedComponents = new Set();
state.unsupportedComponents = new Set();
path.traverse(svgElementVisitor, state);
path.traverse(importDeclarationVisitor, state);
}
}
};
};
var _default = plugin;
exports.default = _default;