rjhilgefort
9/6/2019 - 11:04 PM

TypeScript HOC

import React, { FC, CSSProperties } from 'react'
import { string, number, object, shape } from 'prop-types'
import { getTheme, GetThemeProps } from '@dcf/theme'

import { baseIcons } from './iconMapping'

type P = {
  icon: string
  size?: number
  viewBox?: string
  style?: CSSProperties
  config?: { icons: any }
  className?: string
} & GetThemeProps

export const IconComponent: FC<P> = ({
  theme,
  icon,
  size = theme && theme.defaultIconSize,
  viewBox = '0 0 150 150',
  style = {},
  config = { icons: {} },
  className,
}) => {
  // Merge the config object with base icons. Overwrite base icons if needed
  const icons = { ...baseIcons, ...config.icons }

  const IconComponentToRender = icons[icon]
  if (!IconComponentToRender) {
    return null
  }

  // Theme is null unless using the HOC. The editor also renders the theme null randomly sometimes even when it calls the HOC ¯\_(ツ)_/¯
  const combinedStyle = { stroke: theme && theme.defaultIconColor, ...style }

  return (
    <IconComponentToRender
      className={className}
      width={size}
      height={size}
      viewBox={viewBox}
      style={combinedStyle}
    />
  )
}

IconComponent.propTypes = {
  icon: string.isRequired,
  size: number,
  viewBox: string,
  style: object,
  config: shape({
    icons: object.isRequired,
  }),
  className: string,
}

export const Icon = getTheme<P>(IconComponent)