import { css } from '@emotion/react' ; import { useMemo } from 'react' ; import { forcedGradientStyles } from './gradient-span' ; import { useTheme } from '~/providers/theme' ; import { Component , ComponentProps , ComponentWithTextShadowProps , ComponentWithGradientProps , TextShadowOptions , GradientOptions , gradientToCss , } from '~/types' ; const headingSizes = [ '1' , '2' , '3' , '4' , '5' , '6' ] as const ; const fontSizesKeys = [ '3xs' , '2xs' , 'xs' , 'sm' , 'md' , 'lg' , 'xl' , '2xl' , '3xl' , ... headingSizes , ] as const ; type HeadingSize = typeof headingSizes [ number ] ; type FontSize = typeof fontSizesKeys [ number ] | null | undefined ; export interface HeadingProps extends ComponentProps , ComponentWithTextShadowProps , ComponentWithGradientProps { size ? : HeadingSize ; fontSize ? : FontSize ; } const fontSizeStyles = { '3xs' : '3xs' , '2xs' : '2xs' , xs : 'xs' , sm : 'sm' , md : 'md' , lg : 'lg' , xl : 'xl' , '2xl' : '2xl' , '3xl' : '3xl' , 1 : '3xl' , 2 : '2xl' , 3 : 'xl' , 4 : 'md' , 5 : 'sm' , 6 : 'xs' , } ; const buildGradientAndShadowStyles = ( fontSize ? , shadowColor ? , gradientColor ? , forceGradient ? , isDark ? ) => { const shadowStyles = shadowColor ? [ css `
          text-shadow: var(--text-shadow-size) var(--text-shadow-size) 0
            var(--text-shadow-color);
        ` , isDark ? css `
              text-shadow: none;
            ` : null , css `
          --text-shadow-color: var(--text-shadow-${ shadowColor });
        ` , ] : [ ] ; const gradientCss = gradientToCss ( gradientColor ) ; const gradientStyles = gradientColor ? [ forceGradient || isDark ? forcedGradientStyles : null , css `
          display: inline-block;
        ` , gradientCss , ] : [ ] ; const headingCss = [ css `
      & span.emoji:first-of-type {
        color: rgb(var(--shadow-color));
        margin-right: 0.8rem;
        font-weight: normal;
      }
    ` , fontSize ? css `
          font-size: var(--font-${ fontSizeStyles [ fontSize ] });
        ` : null , ... shadowStyles , ... gradientStyles , ] ; return headingCss ; } ; export const Heading = ( props ) => { const { isDark , themeReady } = useTheme ( ) ; const { size = '1' , fontSize , shadowColor , gradientColor , forceGradient , children , className , style , } = props ; const headingCss = useMemo ( ( ) => { return buildGradientAndShadowStyles ( fontSize , shadowColor , gradientColor , forceGradient , isDark && themeReady ) ; } , [ fontSize , shadowColor , gradientColor , forceGradient , isDark , themeReady ] ) ; const HeadingTag = `h${ size }` as keyof JSX . IntrinsicElements ; return ( < HeadingTag css = { headingCss } className = { className } style = { style } > { children } < /HeadingTag>); } ;