import React, { ReactNode } 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, CurrencyInputBox, CurrencyInputStyled, InputTokenAndMaxBox, MaxButton, PrefixBox, TokenAndMaxBox, TokenBox, TokenLabelFieldBox, TokenSelect, TopBox, TopRightText, } from './TokenLabelField.styled'; export type TokenLabelFieldProps = { allowNegativeValue?: boolean; autoFocus?: 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; min?: number; onBlur?: () => void; onChange?: (value: string | undefined) => void; onFocus?: () => void; onTokenOptionSelected?: (selectedToken: string) => void; placeholder?: string; prefixToken?: string; step?: number; token?: TokenIconProps['token'] | ReactNode; 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 TokenLabelField: React.FunctionComponent = ({ onChange, autoFocus = false, decimalsLimit = 2, maxLength = 18, value = '', defaultValue, disabled = false, 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, onFocus, 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, }) => { 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 : typeof token === 'string' && tokenFormatter(token); const hasPrefixToken = Boolean(prefixToken); const hasTokenOptions = tokenOptions?.length !== 0; return ( {topRightText ? ( {topRightText} ) : null} {hasPrefixToken ? ( {prefixToken} ) : null} raw.replace(/\s/g, '').replace(/,/g, '.')} typographyToken={typographyToken} value={cleanedValue} onBlur={onBlur} onFocus={onFocus} onValueChange={handleOnChange} /> {hasMaxButton ? ( Max ) : null} {token || hasTokenOptions ? ( typeof token === 'string' ? ( {!token || hideTokenIcon ? null : ( )} {!hasTokenOptions ? ( {tokenFormatter(token)} ) : null} {hasTokenOptions ? ( <> {tokenOptions.map((tokenOption) => ( ))} ) : null} ) : ( token ) ) : null} {bottomLeftText && bottomRightTextValue ? ( {bottomLeftText ? ( {bottomLeftText} ) : null} {bottomRightTextValue ? ( ) : null} ) : null} ); };