Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`do not handle path tag inside svg 1`] = `
"function Icon(props) {
return <svg><path></path></svg>;
}"
`;

exports[`do not handle path tag with d attribute outside svg 1`] = `
"function Icon(props) {
return <path d=\\"M10 10\\"></path>;
}"
`;
exports[`handle path tag w/o d attribute 1`] = `
"import { Path as _Path } from \\"three\\";
import { extend as _extend } from \\"@react-three/fiber\\";
_extend({
Path: _Path
});
function Comp(props) {
return <path></path>;
}"
`;
exports[`handles JSX 1`] = `
"import { Mesh as _Mesh, BoxGeometry as _BoxGeometry, MeshBasicMaterial as _MeshBasicMaterial } from \\"three\\";
import { extend as _extend } from \\"@react-three/fiber\\";
Expand Down
33 changes: 33 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,36 @@ it('handles template strings', () => {
)
expect(code).toMatchSnapshot()
})

it('do not handle path tag inside svg',()=>{
const code = transform(
`
function Icon(props) {
return <svg><path></path></svg>;
}
`
)
expect(code).toMatchSnapshot()
})

it('do not handle path tag with d attribute outside svg',()=>{
const code = transform(
`
function Icon(props) {
return <path d="M10 10"></path>;
}
`
)
expect(code).toMatchSnapshot()
})

it('handle path tag w/o d attribute',()=>{
const code = transform(
`
function Comp(props) {
return <path></path>;
}
`
)
expect(code).toMatchSnapshot()
})
25 changes: 25 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,31 @@ export default declare((api) => {

// Parse identifiers (e.g. <mesh />, <animated.mesh />)
let type = 'property' in name ? name.property.name : name.name

// Skip SVG path with 'd' attribute (SVG path data)
if (type === 'path') {
const hasDAttribute = path.node.attributes.some(
(attr) =>
t.isJSXAttribute(attr) &&
t.isJSXIdentifier(attr.name) &&
attr.name.name === 'd'
)
if (hasDAttribute) return

// fallback
let parent: NodePath | null = path.parentPath
while (parent) {
if (
t.isJSXElement(parent.node) &&
t.isJSXIdentifier(parent.node.openingElement.name) &&
parent.node.openingElement.name.name === 'svg'
) {
return
}
parent = parent.parentPath
}
}

const declaration = path.scope.getBinding(type)?.path.node
if (t.isVariableDeclarator(declaration)) {
if (t.isStringLiteral(declaration.init)) {
Expand Down