ifit/ themes

2020 - typescript, react

A private React component library created to use provide theme-based components and styles to multiple webview applications at iFit. I created this library using TypeScript.

withTheme:

import React, { useContext, FC, ReactElement, Context, ReactNode } from "react"
import PropTypes from "prop-types"
import { ThemeContext, ThemeContextValues } from "../ThemeContext"

export enum Themes {
  LIGHT = "light-theme",
  DARK = "dark-theme",
  VAULT = "vault-theme",
}

export type Props = {
  customContext?: Context<ThemeContextValues>
  children?: ReactNode
}

function setThemedName(name: string): string {
  if (!name) return null
  return `Themed${name}`
}

function getDisplayName({
  displayName,
  name,
}: {
  displayName?: string
  name?: string
}): string {
  return setThemedName(displayName || name) || "ThemedComponent"
}

export function withTheme(WrappedComponent): FC {
  function WithTheme(props: Props): ReactElement {
    const { theme } = useContext(props.customContext || ThemeContext)
    return (
      <WrappedComponent themeClass={Themes[theme] || Themes.LIGHT} {...props} />
    )
  }

  WithTheme.propTypes = {
    customContext: PropTypes.shape({
      theme: PropTypes.string,
    }),
  }

  WithTheme.displayName = getDisplayName(WrappedComponent)

  return WithTheme
}

Example usage:

import React from "react"
import { withTheme } from "@ifit/themes/withTheme"

// themeClass is provided by withTheme
function HelloName({ name, themeClass }) {
  return <div className={`hello-name ${themeClass}`}>Hello, {name}.</div>
}

export default withTheme(HelloName)