import React, { FC, forwardRef } from 'react'; import { formatValue } from 'react-currency-input-field'; import { ColorTokens } from '../../../foundation/Colors'; import { TypographyTokens } from '../../../foundation/Typography'; import { browserI18n } from '../../../utils/browser-i18n'; import { ExclaimTooltipProps } from '../../ExclaimTooltip'; import { TokenIcon, TokenIconProps } from '../../Icons'; import { ToggleCaret } from '../../ToggleCaret'; import { TokenTypography } from '../../TokenTypography'; import { TooltipLabel } from '../../TooltipLabel'; import { Typography } from '../../Typography'; import { FieldStyleProps } from '../_common/common.styled'; import { MaxConfig } from '../_common/types'; import { BottomBox, CurrencyInputBottomBox, CurrencyInputBox, CurrencyInputStyled, FloatingBox, LeftFloatingBox, MaxButton, TokenBox, TokenFieldBox, TokenSelect, TopBox, } from './TokenField.styled'; export type TokenFieldProps = { allowNegativeValue?: boolean; bottomLeftText?: string; bottomLeftTextColorToken?: ColorTokens; bottomLeftTextTypographyToken?: TypographyTokens; bottomRightTextColorToken?: ColorTokens; bottomRightTextDifferenceColorToken?: ColorTokens; bottomRightTextDifferenceValue?: number; bottomRightTextToken?: string; bottomRightTextTokenColorToken?: ColorTokens; bottomRightTextTypographyToken?: TypographyTokens; bottomRightTextValue?: string | number; className?: string; decimalsLimit?: number; defaultValue?: number | string; disabled?: boolean; error?: boolean; hideTokenIcon?: boolean; id?: string; label?: string; labelAttentionIndicatorColorToken?: ColorTokens; labelColorToken?: ColorTokens; labelTypographyToken?: TypographyTokens; locale?: string; max?: MaxConfig; maxLength?: number | undefined; min?: number; onBlur?: () => void; onChange?: (value: string | undefined) => void; onFocus?: () => void; onTokenOptionSelected?: (selectedToken: string) => void; placeholder?: string; prefixToken?: string; step?: number; token?: TokenIconProps['token']; tokenColorToken?: ColorTokens; tokenFormatter?: (token: string | undefined) => string; tokenOptions?: string[]; tokenTypographyToken?: TypographyTokens; tooltip?: ExclaimTooltipProps['children']; topRightText?: string; topRightTextColorToken?: ColorTokens; topRightTextTypographyToken?: TypographyTokens; value?: string; } & FieldStyleProps; const defaultTokenFormatter = (token: string | undefined) => token; export const TokenField: FC = forwardRef( ( { onChange, decimalsLimit = 2, maxLength = 18, value = '', defaultValue, disabled, error, typographyToken = 'bodyMediumBold', placeholder, labelColorToken = 'white300', labelTypographyToken = 'bodySmallMedium', tooltip, label, className, topRightTextTypographyToken = 'bodyXSmallMedium', topRightTextColorToken = 'white300', topRightText, bottomLeftTextTypographyToken = 'bodyXSmallMedium', bottomLeftTextColorToken = 'white300', bottomLeftText, token, bottomRightTextTypographyToken = 'bodyXSmallMedium', bottomRightTextColorToken = 'white950', bottomRightTextDifferenceColorToken, bottomRightTextTokenColorToken, bottomRightTextValue, bottomRightTextToken, bottomRightTextDifferenceValue, allowNegativeValue, onBlur, min, max, step, labelAttentionIndicatorColorToken, tokenFormatter = defaultTokenFormatter, tokenOptions = [], onTokenOptionSelected, prefixToken, borderColorToken = 'black700', backgroundColorToken = 'black900', hoverBackgroundColorToken = 'black800', disabledBackgroundColorToken = 'black900', placeholderColorToken = 'white950', disabledColorToken = 'white950', errorBorderColorToken = 'error800', errorColorToken = 'error400', colorToken = 'white100', hoverBorderColorToken = 'black700', hoverErrorBorderColorToken = 'error800', hoverColorToken = colorToken, hoverErrorColorToken = 'error100', disabledBorderColorToken = 'black700', hideTokenIcon = false, tokenColorToken = 'white100', tokenTypographyToken = 'bodyMediumMedium', locale = navigator.language, id, onFocus, }, ref, ) => { const { thousands } = browserI18n(locale); const cleanedValue = value.replace(new RegExp(`\\${thousands}`, 'g'), ''); const hasMaxButton = Boolean(max && max.showButton); const handleOnChange = (newValue: string | undefined) => { if (newValue === cleanedValue) { return; } typeof onChange === 'function' && onChange(newValue); }; const handleOnTokenOptionChange = (event: React.ChangeEvent) => { onTokenOptionSelected && onTokenOptionSelected(event.target.value); }; const bottomRightTextTokenComputed = bottomRightTextToken ? bottomRightTextToken : tokenFormatter(token); const hasPrefixToken = Boolean(prefixToken); const hasTokenOptions = tokenOptions?.length !== 0; return ( {topRightText ? ( {topRightText} ) : null} {hasPrefixToken ? ( {prefixToken} ) : null} {hasMaxButton ? ( Max ) : null} {token || hasTokenOptions ? ( {!token || hideTokenIcon ? null : ( )} {!hasTokenOptions ? ( {tokenFormatter(token)} ) : null} {hasTokenOptions ? ( {tokenOptions.map((tokenOption) => ( ))} ) : null} ) : null} {bottomLeftText && bottomRightTextValue ? ( {bottomLeftText ? ( {bottomLeftText} ) : null} {bottomRightTextValue ? ( ) : null} ) : null} ); }, );