import * as React from 'react' import type { ForwardedRef, PropsWithoutRef, RefAttributes } from 'react' import styled, { css } from 'styled-components' import { createSVGGradient, generateGradientId } from './gradient' const IconWrap = styled.div<{ $gradientId?: string }>` display: contents; ${(props) => props.$gradientId ? css` svg path { fill: url(#${props.$gradientId}); } ` : ''} ` const Container = styled.div<{ $h: number; $w: number }>` box-sizing: border-box; display: flex; align-items: center; justify-content: center; flex-shrink: 0; height: ${(props) => props.$h}px; min-height: ${(props) => props.$h}px; width: ${(props) => props.$w}px; ` const HiddenSVG = styled.svg` display: block; position: absolute; width: 0; height: 0; overflow: hidden; ` const DEFAULT_SIZE = { wrapper: 36, // @planview/pv-utilities/size/small svg: 16, // @planview/pv-utilities/icon-size/medium } type IconAndContainerSize = { svg: number wrapper: number } export type IconProps = React.SVGAttributes & React.HTMLAttributes & { /** * Color can be a string color or one of the predefined gradients `anvi` or `anvi-inverse` */ color?: 'anvi' | 'anvi-inverse' | (string & {}) /** * Size can be a number (applies to both icon and container) or an object to define different sizes for icon and container */ size?: number | IconAndContainerSize } export function withIconWrapper( SvgIcon: React.ForwardRefExoticComponent< PropsWithoutRef> & RefAttributes >, name: string ) { const GenIcon: React.ForwardRefRenderFunction< SVGSVGElement | HTMLDivElement, IconProps > = ({ color, size = DEFAULT_SIZE, ...props }, ref) => { const dataTestId = `svg-icon-${name}`.toLowerCase() const gradientId = React.useMemo( () => color === 'anvi' || color === 'anvi-inverse' ? generateGradientId(color) : undefined, [color] ) const gradientType = color === 'anvi' || color === 'anvi-inverse' ? color : null let comp = null if (typeof size === 'number') { comp = (