|
- import * as React from 'react'
- import * as PropTypes from 'prop-types'
- import * as FeatherIcon from 'react-feather'
- import styled from 'styled-components'
- import { pascalCase, pascalCaseTransformMerge } from 'pascal-case'
- import splitValueAndUnit from '../../services/splitValueAndUnit'
-
- const Label = styled('span')({
- position: 'absolute',
- left: -999999,
- width: 1,
- height: 1,
- ':empty': {
- display: 'none',
- },
- })
-
- const StyledIcon = styled('svg')({
- stroke: 'currentColor',
- strokeLinecap: 'round',
- display: 'inline-block',
- verticalAlign: 'middle',
- })
-
- const propTypes = {
- /**
- * Name of the icon to display.
- */
- name: PropTypes.string.isRequired,
- /**
- * Width of the icon's strokes.
- */
- weight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
- /**
- * Size of the icon. This controls both the width and the height.
- */
- size: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
- /**
- * CSS style of the icon. For icon dimensions, use `size` instead.
- */
- style: PropTypes.object,
- /**
- * Describe of what the component represents.
- */
- label: PropTypes.string,
- /**
- * Class name used for styling.
- */
- className: PropTypes.string,
- }
-
- type Props = PropTypes.InferProps<typeof propTypes>
-
- const Icon: React.FC<Props> = ({
- name,
- weight = '0.125rem',
- size = '1.5rem',
- style = {},
- label = name,
- className = '',
- ...etcProps
- }) => {
- const iconName = pascalCase(name, { transform: pascalCaseTransformMerge })
- const { [iconName as keyof typeof FeatherIcon]: TheIcon = null } = FeatherIcon
- const { magnitude: sizeValue, unit: sizeUnit } = splitValueAndUnit(size)
- const { magnitude: weightValue } = splitValueAndUnit(weight)
- const factor = weightValue * (3 / 2)
-
- if (TheIcon !== null) {
- return (
- <span {...etcProps} style={style!}>
- <StyledIcon
- className={className!}
- as={TheIcon}
- size={undefined}
- color={undefined}
- strokeLinecap={undefined}
- strokeWidth={undefined}
- style={{
- width: size!,
- height: size!,
- strokeWidth: `${factor / sizeValue}${sizeUnit}`,
- }}
- aria-label={label!}
- />
- <Label aria-hidden="true">{label}</Label>
- </span>
- )
- }
-
- return null
- }
-
- Icon.propTypes = propTypes
-
- Icon.displayName = 'Icon'
-
- export default Icon
|