/
index.js
75 lines (61 loc) · 1.83 KB
/
index.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
import React from 'react'
import PropTypes from 'prop-types'
const sizeMap = {
small: 16,
medium: 32,
large: 64
}
const alignMap = {
top: 'text-top',
middle: 'middle'
}
const defaultSize = [16, 16]
export default function Octicon(props) {
const {ariaLabel, children, className, height, icon: Icon, size, verticalAlign, width} = props
const child = typeof Icon === 'function' ? <Icon /> : React.Children.only(children)
const widthHeight = child.type.size || defaultSize
const attrs = {
'aria-hidden': ariaLabel ? 'false' : 'true',
'aria-label': ariaLabel,
className,
height,
role: 'img',
viewBox: [0, 0, ...widthHeight].join(' ')
}
if (width && height) {
Object.assign(attrs, {width, height})
} else {
const dims = {width: widthHeight[0], height: widthHeight[1]}
const given = width ? 'width' : 'height'
const computed = given === 'width' ? 'height' : 'width'
attrs[given] = width || height || sizeMap[size] || size
attrs[computed] = attrs[given] * (dims[computed] / dims[given])
}
attrs.style = {
display: 'inline-block',
fill: 'currentColor',
userSelect: 'none',
verticalAlign: alignMap[verticalAlign] || verticalAlign
}
return <svg {...attrs}>{child}</svg>
}
Octicon.defaultProps = {
className: 'octicon',
size: 16,
verticalAlign: 'text-bottom'
}
Octicon.propTypes = {
ariaLabel: PropTypes.string,
children: PropTypes.element,
height: PropTypes.number,
icon: PropTypes.func,
size: PropTypes.oneOfType([PropTypes.number, PropTypes.oneOf(Object.keys(sizeMap))]),
verticalAlign: PropTypes.oneOf(['middle', 'text-bottom', 'text-top', 'top', 'unset']),
width: PropTypes.number
}
// Helper since TS makes this painful
export function createIcon(component, size) {
component.size = size
return component
}
export * from './__generated__/icons'