/* eslint-disable @typescript-eslint/no-explicit-any */ import { allColors, utils } from '@fuel-ui/css'; import { createStyle, useStyles } from '~/hooks'; import { Components } from '~/utils/components-list'; import { _unstable_createComponent, _unstable_createEl, createPolymorphicComponent, } from '../../utils'; import { createIcon } from '../Button'; import type * as t from './defs'; function getIconSize(as: t.HeadingProps['as'], iconSize?: number) { if (iconSize) return iconSize; if (as === 'h1' || as === 'h2') return 22; if (as === 'h5' || as === 'h6') return 16; return 18; } const _Heading = _unstable_createComponent( Components.Heading, ({ as = 'h2', fontSize, color = 'textHeading', iconColor = 'textIcon', iconSize: initialIconSize, leftIcon, rightIcon, leftIconAriaLabel, rightIconAriaLabel, children, css, ...props }) => { const iconSize = getIconSize(as, initialIconSize); const iconLeft = createIcon( leftIcon, leftIconAriaLabel, iconSize, iconColor, ); const iconRight = createIcon( rightIcon, rightIconAriaLabel, iconSize, iconColor, ); const withIcon = Boolean(leftIcon || rightIcon); const classes = useStyles(styles, { ...props, fontSize, as, withIcon, css: { color: `$${color}`, ...css, }, } as any); const itemProps = { ...props, ...classes.root, role: 'heading' }; return _unstable_createEl( as, itemProps, <> {iconLeft} {children} {iconRight} , ); }, ); export const Heading = createPolymorphicComponent(_Heading); const styles = createStyle(Components.Heading, { root: { mt: '0.5rem', mb: '1.25rem', letterSpacing: '$tight', color: '$intentsBase12', fontFamily: '$heading', fontWeight: '$normal', variants: { // FIX: adjust type type fontSize: (utils.textSize.__keys as any[]).reduce( (obj, key) => ({ ...obj, [key]: { textSize: key } }), {}, ), // FIX: adjust type type fontColor: (allColors as any[]).reduce( (obj, key) => ({ ...obj, [key]: { color: `$${key}` } }), {}, ), as: { h1: { textSize: '4xl', }, h2: { textSize: '3xl', }, h3: { textSize: '2xl', }, h4: { textSize: 'xl', }, h5: { textSize: 'lg', }, h6: { textSize: 'base', }, }, withIcon: { true: { display: 'inline-flex', gap: '$2', }, }, }, defaultVariants: { fontSize: 'md', fontColor: 'fontColor', }, }, });