Skip to content

Commit

Permalink
Merge pull request #414 from gregberge/typescript-support
Browse files Browse the repository at this point in the history
feat: add typescript option
  • Loading branch information
gregberge authored Mar 22, 2020
2 parents c5430f9 + 30362db commit c380147
Show file tree
Hide file tree
Showing 15 changed files with 791 additions and 205 deletions.
11 changes: 11 additions & 0 deletions __fixtures__/simple-existing/File..js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react'

function SvgFile(props) {
return (
<svg width={48} height={1} {...props}>
<path d="M0 0h48v1H0z" fill="#063855" fillRule="evenodd" />
</svg>
)
}

export default SvgFile
1 change: 1 addition & 0 deletions __fixtures__/simple-existing/index..js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as File. } from './File.'
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[` 1`] = `
"import * as React from 'react';
const MyComponent = () => <main>{<svg><g /></svg>}</main>;
export default MyComponent;"
`;

exports[` 2`] = `
"import * as React from 'react';
const MyComponent = () => <main>{<svg><g /></svg>}</main>;
export default MyComponent;"
`;

exports[`plugin javascript custom templates support basic template 1`] = `
"import * as React from 'react';
const MyComponent = () => <svg><g /></svg>;
export default MyComponent;"
`;

exports[`plugin javascript custom templates supports TypeScript template 1`] = `
"import * as React from 'react';
const MyComponent = (props: React.SVGProps<SVGSVGElement>) => <svg><g /></svg>;
export default MyComponent;"
`;
exports[`plugin javascript custom templates supports template that does not return an array 1`] = `"<svg><g /></svg>;"`;
exports[`plugin javascript transforms whole program 1`] = `
"import * as React from \\"react\\";
function SvgComponent() {
return <svg><g /></svg>;
}
export default SvgComponent;"
`;
exports[`plugin javascript with "expandProps" add props 1`] = `
"import * as React from \\"react\\";
function SvgComponent(props) {
return <svg><g /></svg>;
}
export default SvgComponent;"
`;
exports[`plugin javascript with "memo" option wrap component in "React.memo" 1`] = `
"import * as React from \\"react\\";
function SvgComponent() {
return <svg><g /></svg>;
}
const MemoSvgComponent = React.memo(SvgComponent);
export default MemoSvgComponent;"
`;
exports[`plugin javascript with "native" option adds import from "react-native-svg" 1`] = `
"import * as React from \\"react\\";
import Svg from \\"react-native-svg\\";
function SvgComponent() {
return <Svg><g /></Svg>;
}
export default SvgComponent;"
`;
exports[`plugin javascript with "native.expo" option adds import from "react-native-svg" & from "expo" 1`] = `
"import * as React from \\"react\\";
import \\"expo\\";
function SvgComponent() {
return <Svg><g /></Svg>;
}
export default SvgComponent;"
`;
exports[`plugin javascript with "ref" and "expandProps" option expands props 1`] = `
"import * as React from \\"react\\";
function SvgComponent({
svgRef,
...props
}) {
return <svg><g /></svg>;
}
const ForwardRef = React.forwardRef((props, ref) => <SvgComponent svgRef={ref} {...props} />);
export default ForwardRef;"
`;
exports[`plugin javascript with "ref" option adds ForwardRef component 1`] = `
"import * as React from \\"react\\";
function SvgComponent({
svgRef
}) {
return <svg><g /></svg>;
}
const ForwardRef = React.forwardRef((props, ref) => <SvgComponent svgRef={ref} {...props} />);
export default ForwardRef;"
`;
exports[`plugin javascript with "titleProp" adds "titleProp" and "titleId" prop 1`] = `
"import * as React from \\"react\\";
function SvgComponent({
title,
titleId
}) {
return <svg><g /></svg>;
}
export default SvgComponent;"
`;
exports[`plugin javascript with both "memo" and "ref" option wrap component in "React.memo" and "React.forwardRef" 1`] = `
"import * as React from \\"react\\";
function SvgComponent({
svgRef
}) {
return <svg><g /></svg>;
}
const MemoSvgComponent = React.memo(SvgComponent);
const ForwardRef = React.forwardRef((props, ref) => <MemoSvgComponent svgRef={ref} {...props} />);
export default ForwardRef;"
`;
exports[`plugin typescript custom templates support basic template 1`] = `
"import * as React from 'react';
const MyComponent = () => <svg><g /></svg>;
export default MyComponent;"
`;
exports[`plugin typescript custom templates supports TypeScript template 1`] = `
"import * as React from 'react';
const MyComponent = (props: React.SVGProps<SVGSVGElement>) => <svg><g /></svg>;
export default MyComponent;"
`;
exports[`plugin typescript custom templates supports template that does not return an array 1`] = `"<svg><g /></svg>;"`;
exports[`plugin typescript transforms whole program 1`] = `
"import * as React from \\"react\\";
function SvgComponent() {
return <svg><g /></svg>;
}
export default SvgComponent;"
`;
exports[`plugin typescript with "expandProps" add props 1`] = `
"import * as React from \\"react\\";
function SvgComponent(props: React.SVGProps<SVGSVGElement>) {
return <svg><g /></svg>;
}
export default SvgComponent;"
`;
exports[`plugin typescript with "memo" option wrap component in "React.memo" 1`] = `
"import * as React from \\"react\\";
function SvgComponent() {
return <svg><g /></svg>;
}
const MemoSvgComponent = React.memo(SvgComponent);
export default MemoSvgComponent;"
`;
exports[`plugin typescript with "native" option adds import from "react-native-svg" 1`] = `
"import * as React from \\"react\\";
import Svg from \\"react-native-svg\\";
function SvgComponent() {
return <Svg><g /></Svg>;
}
export default SvgComponent;"
`;
exports[`plugin typescript with "native.expo" option adds import from "react-native-svg" & from "expo" 1`] = `
"import * as React from \\"react\\";
import \\"expo\\";
function SvgComponent() {
return <Svg><g /></Svg>;
}
export default SvgComponent;"
`;
exports[`plugin typescript with "ref" and "expandProps" option expands props 1`] = `
"import * as React from \\"react\\";
interface SVGRProps {
svgRef?: React.Ref<SVGSVGElement>
}
function SvgComponent({
svgRef,
...props
}: React.SVGProps<SVGSVGElement> & SVGRProps) {
return <svg><g /></svg>;
}
const ForwardRef = React.forwardRef((props, ref) => <SvgComponent svgRef={ref} {...props} />);
export default ForwardRef;"
`;
exports[`plugin typescript with "ref" option adds ForwardRef component 1`] = `
"import * as React from \\"react\\";
interface SVGRProps {
svgRef?: React.Ref<SVGSVGElement>
}
function SvgComponent({
svgRef
}: SVGRProps) {
return <svg><g /></svg>;
}
const ForwardRef = React.forwardRef((props, ref) => <SvgComponent svgRef={ref} {...props} />);
export default ForwardRef;"
`;
exports[`plugin typescript with "titleProp" adds "titleProp" and "titleId" prop 1`] = `
"import * as React from \\"react\\";
interface SVGRProps {
title?: String,
titleId?: String,
}
function SvgComponent({
title,
titleId
}: SVGRProps) {
return <svg><g /></svg>;
}
export default SvgComponent;"
`;
exports[`plugin typescript with both "memo" and "ref" option wrap component in "React.memo" and "React.forwardRef" 1`] = `
"import * as React from \\"react\\";
interface SVGRProps {
svgRef?: React.Ref<SVGSVGElement>
}
function SvgComponent({
svgRef
}: SVGRProps) {
return <svg><g /></svg>;
}
const MemoSvgComponent = React.memo(SvgComponent);
const ForwardRef = React.forwardRef((props, ref) => <MemoSvgComponent svgRef={ref} {...props} />);
export default ForwardRef;"
`;
17 changes: 13 additions & 4 deletions packages/babel-plugin-transform-svg-component/src/index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import { getProps, getImport, getExport } from './util'
import { getProps, getImport, getExport, getInterface } from './util'

function defaultTemplate(
{ template },
opts,
{ imports, componentName, props, jsx, exports },
{ imports, interfaces, componentName, props, jsx, exports },
) {
return template.ast`${imports}
const plugins = ['jsx']
if (opts.typescript) {
plugins.push('typescript')
}
const typeScriptTpl = template.smart({ plugins })
return typeScriptTpl.ast`${imports}
${interfaces}
function ${componentName}(${props}) {
return ${jsx};
}
${exports}
`
`
}

const plugin = (api, opts) => ({
Expand All @@ -20,6 +28,7 @@ const plugin = (api, opts) => ({
const template = opts.template || defaultTemplate
const body = template(api, opts, {
componentName: t.identifier(opts.state.componentName),
interfaces: getInterface(api, opts),
props: getProps(api, opts),
imports: getImport(api, opts),
exports: getExport(api, opts),
Expand Down
Loading

1 comment on commit c380147

@vercel
Copy link

@vercel vercel bot commented on c380147 Mar 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.