Skip to content

Commit

Permalink
feat: add ref option (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
lifeiscontent authored and gregberge committed Dec 12, 2017
1 parent 82023ad commit 86e0bda
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 29 deletions.
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ Options:
--template <file> specify a custom template to use
--no-expand-props disable props expanding (default: true)
--ids keep ids within the svg
--ref add svgRef prop to svg
--icon use "1em" as width and height
--no-view-box remove viewBox (default: true)
--native add react-native support with react-native-svg
Expand Down Expand Up @@ -167,10 +168,23 @@ $ svgr --template path/to/template.js my-icon.svg
**Example of template:**

```js
module.exports = (opts = {}) => (code, state) => `import React from 'react'
const ${state.componentName} = (${opts.expandProps ? 'props' : ''}) => ${code}
export default ${state.componentName}
`
export default (opts = {}) => {
let props = ''

if (opts.expandProps && opts.ref) {
props = '{svgRef, ...props}'
} else if (opts.expandProps) {
props = 'props'
} else if (opts.ref) {
props = '{svgRef}'
}

return (code, state) => `import React from 'react'
const ${state.componentName} = (${props}) => ${code}
export default ${state.componentName}`
}
```

## Node API usage
Expand Down Expand Up @@ -319,6 +333,14 @@ using CSS or third party library (eg:
| ------- | ------------ | ------------- |
| `false` | `--ids` | `ids: <bool>` |

### 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

| Default | CLI Override | API Override |
| ------- | ------------ | ------------- |
| `false` | `--ref` | `ref: <bool>` |

### Replace attribute value

Replace an attribute value by an other. The main usage of this option is to
Expand Down
30 changes: 30 additions & 0 deletions src/cli/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,36 @@ export default One;
"
`;

exports[`cli --ref --no-expand-props 1`] = `
"import React from \\"react\\";
const One = ({ svgRef }) => (
<svg width={48} height={1} viewBox=\\"0 0 48 1\\" ref={svgRef}>
<title>Rectangle 5</title>
<path d=\\"M0 0h48v1H0z\\" fill=\\"#063855\\" fillRule=\\"evenodd\\" />
</svg>
);
export default One;
"
`;

exports[`cli --ref 1`] = `
"import React from \\"react\\";
const One = ({ svgRef, ...props }) => (
<svg width={48} height={1} viewBox=\\"0 0 48 1\\" ref={svgRef} {...props}>
<title>Rectangle 5</title>
<path d=\\"M0 0h48v1H0z\\" fill=\\"#063855\\" fillRule=\\"evenodd\\" />
</svg>
);
export default One;
"
`;

exports[`cli --replace-attr-value 1`] = `
"import React from \\"react\\";
Expand Down
1 change: 1 addition & 0 deletions src/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ program
.option('--template <file>', 'specify a custom template to use')
.option('--no-expand-props', 'disable props expanding')
.option('--ids', 'keep ids within the svg')
.option('--ref', 'add svgRef prop to svg')
.option('--icon', 'use "1em" as width and height')
.option('--no-view-box', 'remove viewBox')
.option('--native', 'add react-native support with react-native-svg')
Expand Down
40 changes: 18 additions & 22 deletions src/cli/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,12 @@ describe('cli', () => {
})

it('--no-svgo', async () => {
const [stdout] = await exec(
'bin/svgr --no-svgo __fixtures__/one.svg',
)
const [stdout] = await exec('bin/svgr --no-svgo __fixtures__/one.svg')
expect(stdout).toMatchSnapshot()
})

it('--no-prettier', async () => {
const [stdout] = await exec(
'bin/svgr --no-prettier __fixtures__/one.svg',
)
const [stdout] = await exec('bin/svgr --no-prettier __fixtures__/one.svg')
expect(stdout).toMatchSnapshot()
})

Expand All @@ -34,8 +30,18 @@ describe('cli', () => {
})

it('--icon', async () => {
const [stdout] = await exec('bin/svgr --icon __fixtures__/one.svg')
expect(stdout).toMatchSnapshot()
})

it('--ref', async () => {
const [stdout] = await exec('bin/svgr --ref __fixtures__/one.svg')
expect(stdout).toMatchSnapshot()
})

it('--ref --no-expand-props', async () => {
const [stdout] = await exec(
'bin/svgr --icon __fixtures__/one.svg',
'bin/svgr --ref --no-expand-props __fixtures__/one.svg',
)
expect(stdout).toMatchSnapshot()
})
Expand All @@ -46,9 +52,7 @@ describe('cli', () => {
})

it('--no-view-box', async () => {
const [stdout] = await exec(
'bin/svgr --no-view-box __fixtures__/one.svg',
)
const [stdout] = await exec('bin/svgr --no-view-box __fixtures__/one.svg')
expect(stdout).toMatchSnapshot()
})

Expand All @@ -60,23 +64,17 @@ describe('cli', () => {
})

it('--precision', async () => {
const [stdout] = await exec(
'bin/svgr --precision 1 __fixtures__/one.svg',
)
const [stdout] = await exec('bin/svgr --precision 1 __fixtures__/one.svg')
expect(stdout).toMatchSnapshot()
})

it('--no-title', async () => {
const [stdout] = await exec(
'bin/svgr --no-title __fixtures__/one.svg',
)
const [stdout] = await exec('bin/svgr --no-title __fixtures__/one.svg')
expect(stdout).toMatchSnapshot()
})

it('--no-semi', async () => {
const [stdout] = await exec(
'bin/svgr --no-semi __fixtures__/one.svg',
)
const [stdout] = await exec('bin/svgr --no-semi __fixtures__/one.svg')
expect(stdout).toMatchSnapshot()
})

Expand All @@ -88,9 +86,7 @@ describe('cli', () => {
})

it('--native', async () => {
const [stdout] = await exec(
'bin/svgr --native __fixtures__/one.svg',
)
const [stdout] = await exec('bin/svgr --native __fixtures__/one.svg')
expect(stdout).toMatchSnapshot()
})

Expand Down
3 changes: 3 additions & 0 deletions src/configToOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import wrapIntoNativeComponent from './transforms/wrapIntoNativeComponent'
import stripAttribute from './h2x/stripAttribute'
import emSize from './h2x/emSize'
import expandProps from './h2x/expandProps'
import svgRef from './h2x/svgRef'
import replaceAttrValue from './h2x/replaceAttrValue'
import removeComments from './h2x/removeComments'
import removeStyle from './h2x/removeStyle'
import toReactNative from './h2x/toReactNative'

const defaultConfig = {
ref: false,
svgo: true,
prettier: true,
native: false,
Expand Down Expand Up @@ -41,6 +43,7 @@ function configToOptions(config = {}) {
config.replaceAttrValues.forEach(([oldValue, newValue]) => {
plugins.push(replaceAttrValue(oldValue, newValue))
})
if (config.ref) plugins.push(svgRef)
if (config.expandProps) plugins.push(expandProps)
if (config.native) plugins.push(toReactNative)

Expand Down
23 changes: 23 additions & 0 deletions src/h2x/svgRef.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { JSXAttribute } from 'h2x-plugin-jsx'

const svgRef = () => ({
visitor: {
JSXElement: {
enter(path) {
if (
path.node.name === 'svg' &&
!path.node.attributes.some(attr => attr && attr.name === 'ref')
) {
const props = new JSXAttribute()
props.name = 'ref'
props.value = 'svgRef'
props.litteral = true
path.node.attributes.push(props)
path.replace(path.node)
}
},
},
},
})

export default svgRef
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { pascalCase } from './transforms/rename'
import stripAttribute from './h2x/stripAttribute'
import emSize from './h2x/emSize'
import expandProps from './h2x/expandProps'
import svgRef from './h2x/svgRef'
import replaceAttrValue from './h2x/replaceAttrValue'
import removeComments from './h2x/removeComments'
import removeStyle from './h2x/removeStyle'
Expand All @@ -20,6 +21,7 @@ export {
emSize,
expandProps,
replaceAttrValue,
svgRef,
wrapIntoComponent,
removeComments,
removeStyle,
Expand Down
16 changes: 14 additions & 2 deletions src/transforms/wrapIntoComponent.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
export default (opts = {}) => (code, state) => `import React from 'react'
export default (opts = {}) => {
let props = ''

const ${state.componentName} = (${opts.expandProps ? 'props' : ''}) => ${code}
if (opts.expandProps && opts.ref) {
props = '{svgRef, ...props}'
} else if (opts.expandProps) {
props = 'props'
} else if (opts.ref) {
props = '{svgRef}'
}

return (code, state) => `import React from 'react'
const ${state.componentName} = (${props}) => ${code}
export default ${state.componentName}`
}
12 changes: 11 additions & 1 deletion src/transforms/wrapIntoNativeComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,24 @@ export default (opts = {}) => (code, state) => {
unsupportedComponents = new Set(),
} = state

let props = ''

if (opts.expandProps && opts.ref) {
props = '{svgRef, ...props}'
} else if (opts.expandProps) {
props = 'props'
} else if (opts.ref) {
props = '{svgRef}'
}

return `import React from 'react'
import Svg, { ${componentsToList(
reactNativeSvgReplacedComponents,
)} } from 'react-native-svg';
${logUnsupportedComponents(unsupportedComponents)}
const ${state.componentName} = (${opts.expandProps ? 'props' : ''}) => ${code}
const ${state.componentName} = (${props}) => ${code}
export default ${state.componentName}`
}

0 comments on commit 86e0bda

Please sign in to comment.