|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- 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>
-
- /**
- * Component for displaying graphical icons.
- *
- * @see {@link //feathericons.com|Feather Icons} for a complete list of icons.
- * @param {string} name - Name of the icon to display.
- * @param {string} weight - Width of the icon's strokes.
- * @param {string | number} [size] - Size of the icon. This controls both the width and the height.
- * @param {CSSProperties} [style] - CSS style of the icon. For icon dimensions, use `size` instead.
- * @param {string} [label] - Describe of what the component represents.
- * @param {string} [className] - Class name used for styling.
- * @param {object} etcProps - The rest of the props.
- * @returns {React.ReactElement | null} - The component elements.
- */
- 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
|