-
Notifications
You must be signed in to change notification settings - Fork 106
/
svgr-template.js
104 lines (85 loc) · 2.41 KB
/
svgr-template.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
const {
identifier,
jsxAttribute,
jsxIdentifier,
jsxExpressionContainer,
isJSXElement
} = require('@babel/types')
const webImports = `
import {css, cx} from '@emotion/css'
`
const nativeImports = `
import {css} from '@emotion/native'
import Animated from 'react-native-reanimated'
import {Path as RNSVGPath} from 'react-native-svg'
const AnimatedPath = Animated.createAnimatedComponent(RNSVGPath)
`
const webStyles = `
const {className: classNameProp} = other
const className = css({
filter: shadow ? theme.shadows.drop : undefined,
minHeight: height,
minWidth: width
})
other.className = cx(className, classNameProp)
`
const nativeStyles = `
const {style: styleProp} = other
const style = shadow ? css(theme.shadows[shadow]) : undefined
other.style = style ? [style, styleProp] : styleProp
`
const updatePathElements = (element) => {
if (element.openingElement && element.openingElement.name.name === 'path') {
element.openingElement.attributes.push(
jsxAttribute(
jsxIdentifier('animatedProps'),
jsxExpressionContainer(identifier('animatedProps'))
)
)
}
element.children = element.children.map((child) =>
isJSXElement(child) ? updatePathElements(child) : child
)
return element
}
const template = (variables, { tpl, options }) => {
const { native } = options
return tpl`
${variables.imports};
import {useTheme} from '@emotion/react'
import {forwardRef} from 'react'
${native ? nativeImports : webImports}
${variables.interfaces};
const ${variables.componentName} = forwardRef((${variables.props}, ref) => {
const theme = useTheme()
let {
color,
size,
sizeH,
sizeW,
height: heightProp,
width: widthProp,
shadow,
animatedProps,
...other
} = props
const height = heightProp ?? theme.iconSizes?.[sizeH ?? size]
if (height) {
other.height = height
}
const width = widthProp ?? theme.iconSizes?.[sizeW ?? size]
if (width) {
other.width = width
}
const fillColor = other.fill ?? theme.color?.icon[color] ?? 'red'
${native ? nativeStyles : webStyles}
other.role = title ? 'img' : undefined
other['aria-hidden'] = title ? undefined : true
props = {...other, ref, fillColor}
${native ? `const Path = animatedProps ? AnimatedPath : RNSVGPath` : ''}
return (${native ? updatePathElements(variables.jsx) : variables.jsx})
});
${variables.exports};
`
}
module.exports = template