diff --git a/packages/babel-plugin-svg-em-dimensions/README.md b/packages/babel-plugin-svg-em-dimensions/README.md
index 215c1d02..b7759641 100644
--- a/packages/babel-plugin-svg-em-dimensions/README.md
+++ b/packages/babel-plugin-svg-em-dimensions/README.md
@@ -12,7 +12,9 @@ npm install --save-dev @svgr/babel-plugin-svg-em-dimensions
```json
{
- "plugins": ["@svgr/babel-plugin-svg-em-dimensions"]
+ "plugins": [
+ ["@svgr/babel-plugin-svg-em-dimensions", { "width": 24, "height": 24 }]
+ ]
}
```
diff --git a/packages/babel-plugin-svg-em-dimensions/src/index.test.ts b/packages/babel-plugin-svg-em-dimensions/src/index.test.ts
index e687647d..5e9d96d6 100644
--- a/packages/babel-plugin-svg-em-dimensions/src/index.test.ts
+++ b/packages/babel-plugin-svg-em-dimensions/src/index.test.ts
@@ -1,9 +1,9 @@
import { transform } from '@babel/core'
-import plugin from '.'
+import plugin, { Options } from '.'
-const testPlugin = (code: string) => {
+const testPlugin = (code: string, options?: Options) => {
const result = transform(code, {
- plugins: ['@babel/plugin-syntax-jsx', plugin],
+ plugins: ['@babel/plugin-syntax-jsx', [plugin, options]],
configFile: false,
})
@@ -11,7 +11,7 @@ const testPlugin = (code: string) => {
}
describe('plugin', () => {
- it('should replace width / height attributes', () => {
+ it('replaces width / height attributes', () => {
expect(
testPlugin(''),
).toMatchInlineSnapshot(
@@ -19,9 +19,23 @@ describe('plugin', () => {
)
})
- it('should add theme if they are not present', () => {
+ it('adds theme if they are not present', () => {
expect(testPlugin('')).toMatchInlineSnapshot(
`";"`,
)
})
+
+ it('accepts numeric values', () => {
+ expect(
+ testPlugin('', { width: 24, height: 24 }),
+ ).toMatchInlineSnapshot(`";"`)
+ })
+
+ it('accepts string values', () => {
+ expect(
+ testPlugin('', { width: '2em', height: '2em' }),
+ ).toMatchInlineSnapshot(
+ `";"`,
+ )
+ })
})
diff --git a/packages/babel-plugin-svg-em-dimensions/src/index.ts b/packages/babel-plugin-svg-em-dimensions/src/index.ts
index 0b24accc..7ef835df 100644
--- a/packages/babel-plugin-svg-em-dimensions/src/index.ts
+++ b/packages/babel-plugin-svg-em-dimensions/src/index.ts
@@ -1,10 +1,26 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
-import { types as t, NodePath } from '@babel/core'
+import { types as t, NodePath, ConfigAPI } from '@babel/core'
const elements = ['svg', 'Svg']
-const value = t.stringLiteral('1em')
-const plugin = () => ({
+export interface Options {
+ width: number | string
+ height: number | string
+}
+
+const getValue = (raw: undefined | number | string) => {
+ if (raw === undefined) return t.stringLiteral('1em')
+ switch (typeof raw) {
+ case 'number':
+ return t.jsxExpressionContainer(t.numericLiteral(raw))
+ case 'string':
+ return t.stringLiteral(raw)
+ default:
+ return t.stringLiteral('1em')
+ }
+}
+
+const plugin = (_: ConfigAPI, opts: Options) => ({
visitor: {
JSXOpeningElement(path: NodePath) {
if (
@@ -14,7 +30,11 @@ const plugin = () => ({
)
return
- const requiredAttributes = ['width', 'height']
+ const values = {
+ width: getValue(opts.width),
+ height: getValue(opts.height),
+ }
+ const requiredAttributes = Object.keys(values)
path.get('attributes').forEach((attributePath) => {
if (!attributePath.isJSXAttribute()) return
@@ -25,14 +45,17 @@ const plugin = () => ({
if (index === -1) return
const valuePath = attributePath.get('value')
- valuePath.replaceWith(value)
+ valuePath.replaceWith(values[namePath.node.name as 'width' | 'height'])
requiredAttributes.splice(index, 1)
})
path.pushContainer(
'attributes',
requiredAttributes.map((attr) =>
- t.jsxAttribute(t.jsxIdentifier(attr), value),
+ t.jsxAttribute(
+ t.jsxIdentifier(attr),
+ values[attr as 'width' | 'height'],
+ ),
),
)
},
diff --git a/packages/babel-preset/src/index.test.ts b/packages/babel-preset/src/index.test.ts
index cd703f29..90073f5a 100644
--- a/packages/babel-preset/src/index.test.ts
+++ b/packages/babel-preset/src/index.test.ts
@@ -17,7 +17,7 @@ const testPreset = (code: string, options: Partial) => {
}
describe('preset', () => {
- it('should handle svgProps', () => {
+ it('handles svgProps', () => {
expect(
testPreset('', {
svgProps: {
@@ -34,7 +34,7 @@ describe('preset', () => {
`)
})
- it('should handle titleProp', () => {
+ it('handles titleProp', () => {
expect(
testPreset('', {
titleProp: true,
@@ -50,7 +50,7 @@ describe('preset', () => {
export default SvgComponent;"
`)
})
- it('should handle titleProp and fallback on existing title', () => {
+ it('handles titleProp and fallback on existing title', () => {
// testing when existing title has string as chilren
expect(
testPreset(``, {
@@ -83,7 +83,7 @@ describe('preset', () => {
`)
})
- it('should handle replaceAttrValues', () => {
+ it('handles replaceAttrValues', () => {
expect(
testPreset('', {
replaceAttrValues: {
@@ -100,7 +100,7 @@ describe('preset', () => {
`)
})
- it('should handle expandProps & icon & dimensions', () => {
+ it('handles expandProps & icon & dimensions', () => {
expect(
testPreset('', {
expandProps: 'end',
@@ -115,4 +115,38 @@ describe('preset', () => {
export default SvgComponent;"
`)
})
+
+ it('handles custom icon size', () => {
+ expect(
+ testPreset('', {
+ expandProps: 'end',
+ icon: 24,
+ dimensions: true,
+ }),
+ ).toMatchInlineSnapshot(`
+ "import * as React from \\"react\\";
+
+ const SvgComponent = props => ;
+
+ export default SvgComponent;"
+ `)
+ })
+
+ it('defaults to 24 on native', () => {
+ expect(
+ testPreset('', {
+ expandProps: 'end',
+ icon: true,
+ native: true,
+ dimensions: true,
+ }),
+ ).toMatchInlineSnapshot(`
+ "import * as React from \\"react\\";
+ import Svg from \\"react-native-svg\\";
+
+ const SvgComponent = props => ;
+
+ export default SvgComponent;"
+ `)
+ })
})
diff --git a/packages/babel-preset/src/index.ts b/packages/babel-preset/src/index.ts
index 66501915..5405a032 100644
--- a/packages/babel-preset/src/index.ts
+++ b/packages/babel-preset/src/index.ts
@@ -20,7 +20,7 @@ export interface Options extends TransformOptions {
titleProp?: boolean
expandProps?: boolean | 'start' | 'end'
dimensions?: boolean
- icon?: boolean
+ icon?: boolean | string | number
native?: boolean
svgProps?: { [key: string]: string }
replaceAttrValues?: { [key: string]: string }
@@ -96,7 +96,18 @@ const plugin = (_: ConfigAPI, opts: Options) => {
const plugins: any[] = [
[transformSvgComponent, opts],
- ...(opts.icon && opts.dimensions ? [svgEmDimensions] : []),
+ ...(opts.icon !== false && opts.dimensions
+ ? [
+ [
+ svgEmDimensions,
+ opts.icon !== true
+ ? { width: opts.icon, height: opts.icon }
+ : opts.native
+ ? { width: 24, height: 24 }
+ : {},
+ ],
+ ]
+ : []),
[
removeJSXAttribute,
{ elements: ['svg', 'Svg'], attributes: toRemoveAttributes },
diff --git a/packages/cli/src/__snapshots__/index.test.ts.snap b/packages/cli/src/__snapshots__/index.test.ts.snap
index 7004f9df..dc21e590 100644
--- a/packages/cli/src/__snapshots__/index.test.ts.snap
+++ b/packages/cli/src/__snapshots__/index.test.ts.snap
@@ -203,6 +203,46 @@ export default SvgFile
"
`;
+exports[`cli should support various args: --icon 2em 1`] = `
+"import * as React from 'react'
+
+const SvgFile = (props) => (
+
+)
+
+export default SvgFile
+
+"
+`;
+
+exports[`cli should support various args: --icon 24 1`] = `
+"import * as React from 'react'
+
+const SvgFile = (props) => (
+
+)
+
+export default SvgFile
+
+"
+`;
+
exports[`cli should support various args: --jsx-runtime automatic 1`] = `
"const SvgFile = (props) => (