Skip to content

Commit

Permalink
Merge pull request #625 from gregberge/icon-size
Browse files Browse the repository at this point in the history
feat: allow to specify icon size
  • Loading branch information
gregberge authored Nov 13, 2021
2 parents 6ba16a3 + 483560d commit 1c5f163
Show file tree
Hide file tree
Showing 12 changed files with 265 additions and 74 deletions.
56 changes: 28 additions & 28 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion packages/babel-plugin-svg-em-dimensions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 }]
]
}
```

Expand Down
24 changes: 19 additions & 5 deletions packages/babel-plugin-svg-em-dimensions/src/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,41 @@
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,
})

return result?.code
}

describe('plugin', () => {
it('should replace width / height attributes', () => {
it('replaces width / height attributes', () => {
expect(
testPlugin('<svg foo="bar" width="100" height="200" />'),
).toMatchInlineSnapshot(
`"<svg foo=\\"bar\\" width=\\"1em\\" height=\\"1em\\" />;"`,
)
})

it('should add theme if they are not present', () => {
it('adds theme if they are not present', () => {
expect(testPlugin('<svg foo="bar" />')).toMatchInlineSnapshot(
`"<svg foo=\\"bar\\" width=\\"1em\\" height=\\"1em\\" />;"`,
)
})

it('accepts numeric values', () => {
expect(
testPlugin('<svg foo="bar" />', { width: 24, height: 24 }),
).toMatchInlineSnapshot(`"<svg foo=\\"bar\\" width={24} height={24} />;"`)
})

it('accepts string values', () => {
expect(
testPlugin('<svg foo="bar" />', { width: '2em', height: '2em' }),
).toMatchInlineSnapshot(
`"<svg foo=\\"bar\\" width=\\"2em\\" height=\\"2em\\" />;"`,
)
})
})
35 changes: 29 additions & 6 deletions packages/babel-plugin-svg-em-dimensions/src/index.ts
Original file line number Diff line number Diff line change
@@ -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<t.JSXOpeningElement>) {
if (
Expand All @@ -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
Expand All @@ -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'],
),
),
)
},
Expand Down
44 changes: 39 additions & 5 deletions packages/babel-preset/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const testPreset = (code: string, options: Partial<Options>) => {
}

describe('preset', () => {
it('should handle svgProps', () => {
it('handles svgProps', () => {
expect(
testPreset('<svg />', {
svgProps: {
Expand All @@ -34,7 +34,7 @@ describe('preset', () => {
`)
})

it('should handle titleProp', () => {
it('handles titleProp', () => {
expect(
testPreset('<svg></svg>', {
titleProp: true,
Expand All @@ -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(`<svg><title>Hello</title></svg>`, {
Expand Down Expand Up @@ -83,7 +83,7 @@ describe('preset', () => {
`)
})

it('should handle replaceAttrValues', () => {
it('handles replaceAttrValues', () => {
expect(
testPreset('<svg a="#000" b="#fff" />', {
replaceAttrValues: {
Expand All @@ -100,7 +100,7 @@ describe('preset', () => {
`)
})

it('should handle expandProps & icon & dimensions', () => {
it('handles expandProps & icon & dimensions', () => {
expect(
testPreset('<svg a="#000" b="#fff" />', {
expandProps: 'end',
Expand All @@ -115,4 +115,38 @@ describe('preset', () => {
export default SvgComponent;"
`)
})

it('handles custom icon size', () => {
expect(
testPreset('<svg a="#000" b="#fff" />', {
expandProps: 'end',
icon: 24,
dimensions: true,
}),
).toMatchInlineSnapshot(`
"import * as React from \\"react\\";
const SvgComponent = props => <svg a=\\"#000\\" b=\\"#fff\\" width={24} height={24} {...props} />;
export default SvgComponent;"
`)
})

it('defaults to 24 on native', () => {
expect(
testPreset('<svg a="#000" b="#fff" />', {
expandProps: 'end',
icon: true,
native: true,
dimensions: true,
}),
).toMatchInlineSnapshot(`
"import * as React from \\"react\\";
import Svg from \\"react-native-svg\\";
const SvgComponent = props => <Svg a=\\"#000\\" b=\\"#fff\\" width={24} height={24} {...props} />;
export default SvgComponent;"
`)
})
})
Loading

1 comment on commit 1c5f163

@vercel
Copy link

@vercel vercel bot commented on 1c5f163 Nov 13, 2021

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.