Skip to content

Commit cbee51c

Browse files
committed
feat: use React.forwardRef
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
1 parent 5cb238e commit cbee51c

File tree

8 files changed

+51
-21
lines changed

8 files changed

+51
-21
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ Options:
106106
--filename-case <case> specify filename case (pascal, kebab, camel) (default: "pascal")
107107
--icon use "1em" as width and height
108108
--native add react-native support with react-native-svg
109-
--ref add svgRef prop to svg
109+
--ref forward ref to SVG root element
110110
--no-dimensions remove width and height from root SVG tag
111111
--no-expand-props disable props expanding
112112
--svg-attributes <property=value> add attributes to the svg element (deprecated)
@@ -377,7 +377,7 @@ Specify SVGO config. [See SVGO options](https://gist.github.com/pladaria/69321af
377377

378378
### Ref
379379

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

382382
| Default | CLI Override | API Override |
383383
| ------- | ------------ | ------------- |

packages/cli/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Options:
2525
--filename-case <case> specify filename case (pascal, kebab, camel) (default: "pascal")
2626
--icon use "1em" as width and height
2727
--native add react-native support with react-native-svg
28-
--ref add svgRef prop to svg
28+
--ref forward ref to SVG root element
2929
--no-dimensions remove width and height from root SVG tag
3030
--no-expand-props disable props expanding
3131
--svg-attributes <property=value> add attributes to the svg element (deprecated)

packages/cli/src/__snapshots__/index.test.js.snap

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,11 @@ const SvgFile = ({ svgRef, ...props }) => (
290290
</svg>
291291
)
292292
293-
export default SvgFile
293+
const ForwardRef = React.forwardRef((props, ref) => (
294+
<SvgFile svgRef={ref} {...props} />
295+
))
296+
297+
export default ForwardRef
294298
295299
"
296300
`;

packages/cli/src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ program
5151
)
5252
.option('--icon', 'use "1em" as width and height')
5353
.option('--native', 'add react-native support with react-native-svg')
54-
.option('--ref', 'add svgRef prop to svg')
54+
.option('--ref', 'forward ref to SVG root element')
5555
.option('--no-dimensions', 'remove width and height from root SVG tag')
5656
.option('--no-expand-props', 'disable props expanding')
5757
.option(

packages/core/src/__snapshots__/convert.test.js.snap

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,11 @@ const SvgComponent = ({ svgRef, ...props }) => (
198198
</svg>
199199
)
200200
201-
export default SvgComponent
201+
const ForwardRef = React.forwardRef((props, ref) => (
202+
<SvgComponent svgRef={ref} {...props} />
203+
))
204+
205+
export default ForwardRef
202206
"
203207
`;
204208

packages/core/src/templates/__snapshots__/reactDomTemplate.test.js.snap

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ exports[`reactDomTemplate should wrap code into a component 3`] = `
2121
2222
const Test = ({ svgRef }) => <Svg />
2323
24-
export default Test"
24+
const ForwardRef = React.forwardRef((props, ref) => <Test svgRef={ref} {...props} />)
25+
26+
export default ForwardRef"
2527
`;
2628

2729
exports[`reactDomTemplate should wrap code into a component 4`] = `
@@ -37,7 +39,9 @@ exports[`reactDomTemplate should wrap code into a component 5`] = `
3739
3840
const Test = ({ svgRef, title }) => <Svg />
3941
40-
export default Test"
42+
const ForwardRef = React.forwardRef((props, ref) => <Test svgRef={ref} {...props} />)
43+
44+
export default ForwardRef"
4145
`;
4246

4347
exports[`reactDomTemplate should wrap code into a component 6`] = `
@@ -53,5 +57,7 @@ exports[`reactDomTemplate should wrap code into a component 7`] = `
5357
5458
const Test = ({ svgRef, ...props }) => <Svg />
5559
56-
export default Test"
60+
const ForwardRef = React.forwardRef((props, ref) => <Test svgRef={ref} {...props} />)
61+
62+
export default ForwardRef"
5763
`;

packages/core/src/templates/reactDomTemplate.js

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
1-
import { getProps } from './util'
1+
import { getProps, getExport, getForwardRef } from './util'
22

33
const reactDomTemplate = (code, config, state) => {
4-
const props = getProps(config)
4+
const props = getProps(config, state)
55

66
let result = `import React from 'react'\n\n`
77
result += `const ${state.componentName} = ${props} => ${code}\n\n`
8-
9-
if (state.webpack && state.webpack.previousExport) {
10-
result += `export default ${state.webpack.previousExport}\n`
11-
result += `export { ${state.componentName} as ReactComponent }`
12-
} else if (state.rollup && state.rollup.previousExport) {
13-
result += `${state.rollup.previousExport}\n`
14-
result += `export { ${state.componentName} as ReactComponent }`
15-
} else {
16-
result += `export default ${state.componentName}`
17-
}
8+
result += getForwardRef(config, state)
9+
result += getExport(config, state)
1810

1911
return result
2012
}

packages/core/src/templates/util.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,27 @@ export const getProps = config => {
99

1010
return `({ ${props.join(', ')} })`
1111
}
12+
13+
export const getExport = (config, state) => {
14+
const component = config.ref ? 'ForwardRef' : state.componentName
15+
if (state.webpack && state.webpack.previousExport) {
16+
let result = ''
17+
result += `export default ${state.webpack.previousExport}\n`
18+
result += `export { ${component} as ReactComponent }`
19+
return result
20+
}
21+
if (state.rollup && state.rollup.previousExport) {
22+
let result = ''
23+
result += `${state.rollup.previousExport}\n`
24+
result += `export { ${component} as ReactComponent }`
25+
return result
26+
}
27+
return `export default ${component}`
28+
}
29+
30+
export const getForwardRef = (config, state) => {
31+
if (!config.ref) return ''
32+
return `const ForwardRef = React.forwardRef((props, ref) => <${
33+
state.componentName
34+
} svgRef={ref} {...props} />)\n\n`
35+
}

0 commit comments

Comments
 (0)