Skip to content

Commit

Permalink
feat: use React.forwardRef
Browse files Browse the repository at this point in the history
BREAKING CHANGE:

"ref" option now uses `React.forwardRef`. You don't have to use "svgRef"
prop, just use "ref" and it will work. `React.forwardRef` requires React
> 16.3.

Closes #184
  • Loading branch information
gregberge committed Sep 30, 2018
1 parent 5cb238e commit cbee51c
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 21 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -106,7 +106,7 @@ Options:
--filename-case <case> specify filename case (pascal, kebab, camel) (default: "pascal")
--icon use "1em" as width and height
--native add react-native support with react-native-svg
--ref add svgRef prop to svg
--ref forward ref to SVG root element
--no-dimensions remove width and height from root SVG tag
--no-expand-props disable props expanding
--svg-attributes <property=value> add attributes to the svg element (deprecated)
Expand Down Expand Up @@ -377,7 +377,7 @@ Specify SVGO config. [See SVGO options](https://gist.github.com/pladaria/69321af

### Ref

Setting this to `true` will allow you to hook into the ref of the svg components that are created by exposing a `svgRef` prop
Setting this to `true` will forward ref to the root SVG tag.

| Default | CLI Override | API Override |
| ------- | ------------ | ------------- |
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/README.md
Expand Up @@ -25,7 +25,7 @@ Options:
--filename-case <case> specify filename case (pascal, kebab, camel) (default: "pascal")
--icon use "1em" as width and height
--native add react-native support with react-native-svg
--ref add svgRef prop to svg
--ref forward ref to SVG root element
--no-dimensions remove width and height from root SVG tag
--no-expand-props disable props expanding
--svg-attributes <property=value> add attributes to the svg element (deprecated)
Expand Down
6 changes: 5 additions & 1 deletion packages/cli/src/__snapshots__/index.test.js.snap
Expand Up @@ -290,7 +290,11 @@ const SvgFile = ({ svgRef, ...props }) => (
</svg>
)
export default SvgFile
const ForwardRef = React.forwardRef((props, ref) => (
<SvgFile svgRef={ref} {...props} />
))
export default ForwardRef
"
`;
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/index.js
Expand Up @@ -51,7 +51,7 @@ program
)
.option('--icon', 'use "1em" as width and height')
.option('--native', 'add react-native support with react-native-svg')
.option('--ref', 'add svgRef prop to svg')
.option('--ref', 'forward ref to SVG root element')
.option('--no-dimensions', 'remove width and height from root SVG tag')
.option('--no-expand-props', 'disable props expanding')
.option(
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/__snapshots__/convert.test.js.snap
Expand Up @@ -198,7 +198,11 @@ const SvgComponent = ({ svgRef, ...props }) => (
</svg>
)
export default SvgComponent
const ForwardRef = React.forwardRef((props, ref) => (
<SvgComponent svgRef={ref} {...props} />
))
export default ForwardRef
"
`;

Expand Down
Expand Up @@ -21,7 +21,9 @@ exports[`reactDomTemplate should wrap code into a component 3`] = `
const Test = ({ svgRef }) => <Svg />
export default Test"
const ForwardRef = React.forwardRef((props, ref) => <Test svgRef={ref} {...props} />)
export default ForwardRef"
`;

exports[`reactDomTemplate should wrap code into a component 4`] = `
Expand All @@ -37,7 +39,9 @@ exports[`reactDomTemplate should wrap code into a component 5`] = `
const Test = ({ svgRef, title }) => <Svg />
export default Test"
const ForwardRef = React.forwardRef((props, ref) => <Test svgRef={ref} {...props} />)
export default ForwardRef"
`;

exports[`reactDomTemplate should wrap code into a component 6`] = `
Expand All @@ -53,5 +57,7 @@ exports[`reactDomTemplate should wrap code into a component 7`] = `
const Test = ({ svgRef, ...props }) => <Svg />
export default Test"
const ForwardRef = React.forwardRef((props, ref) => <Test svgRef={ref} {...props} />)
export default ForwardRef"
`;
16 changes: 4 additions & 12 deletions packages/core/src/templates/reactDomTemplate.js
@@ -1,20 +1,12 @@
import { getProps } from './util'
import { getProps, getExport, getForwardRef } from './util'

const reactDomTemplate = (code, config, state) => {
const props = getProps(config)
const props = getProps(config, state)

let result = `import React from 'react'\n\n`
result += `const ${state.componentName} = ${props} => ${code}\n\n`

if (state.webpack && state.webpack.previousExport) {
result += `export default ${state.webpack.previousExport}\n`
result += `export { ${state.componentName} as ReactComponent }`
} else if (state.rollup && state.rollup.previousExport) {
result += `${state.rollup.previousExport}\n`
result += `export { ${state.componentName} as ReactComponent }`
} else {
result += `export default ${state.componentName}`
}
result += getForwardRef(config, state)
result += getExport(config, state)

return result
}
Expand Down
24 changes: 24 additions & 0 deletions packages/core/src/templates/util.js
Expand Up @@ -9,3 +9,27 @@ export const getProps = config => {

return `({ ${props.join(', ')} })`
}

export const getExport = (config, state) => {
const component = config.ref ? 'ForwardRef' : state.componentName
if (state.webpack && state.webpack.previousExport) {
let result = ''
result += `export default ${state.webpack.previousExport}\n`
result += `export { ${component} as ReactComponent }`
return result
}
if (state.rollup && state.rollup.previousExport) {
let result = ''
result += `${state.rollup.previousExport}\n`
result += `export { ${component} as ReactComponent }`
return result
}
return `export default ${component}`
}

export const getForwardRef = (config, state) => {
if (!config.ref) return ''
return `const ForwardRef = React.forwardRef((props, ref) => <${
state.componentName
} svgRef={ref} {...props} />)\n\n`
}

0 comments on commit cbee51c

Please sign in to comment.