import { NumericFormat } from 'react-number-format'; import { TextField } from '@mui/material'; import { useEffect, useState } from 'react'; import { getCurrencyCharacters, getCurrencyOptions } from '@pega/react-sdk-components/lib/components/field/Currency/currency-utils'; import handleEvent from '@pega/react-sdk-components/lib/components/helpers/event-utils'; import { format } from '@pega/react-sdk-components/lib/components/helpers/formatters'; import { getComponentFromMap } from '@pega/react-sdk-components/lib/bridge/helpers/sdk_component_map'; import type { PConnFieldProps } from '@pega/react-sdk-components/lib/types/PConnProps'; import useStatus from '@pega/react-sdk-components/lib/hooks/useStatus'; import { getFieldSx } from '@pega/react-sdk-components/lib/components/helpers/field-utils'; /* Using react-number-format component here, since it allows formatting decimal values, as per the locale. */ interface DecimalProps extends PConnFieldProps { // If any, enter additional props that only exist on Decimal here currencyISOCode?: string; decimalPrecision?: number; showGroupSeparators?: boolean; formatter?: string; showFieldMessage?: boolean; messageConfig?: { content?: string; visibility?: boolean; }; variant?: string; } export default function Decimal(props: DecimalProps) { // Get emitted components from map (so we can get any override that may exist) const FieldValueList = getComponentFromMap('FieldValueList'); const { getPConnect, label, required, disabled, value = '', validatemessage, /* onChange, onBlur, */ readOnly, helperText, displayMode, hideLabel, currencyISOCode = 'USD', decimalPrecision, showGroupSeparators, testId, placeholder, formatter, showFieldMessage, messageConfig = {} } = props; const [values, setValues] = useState(value.toString()); const pConn = getPConnect(); const actions = pConn.getActionsApi(); const propName = (pConn.getStateProps() as any).value; const eligibleForFieldWarning = showFieldMessage && messageConfig.visibility && !readOnly; const helperTextToDisplay = validatemessage || (eligibleForFieldWarning ? messageConfig.content : helperText); const status = useStatus({ showFieldMessage, messageVisibility: messageConfig.visibility, validatemessage, readOnly }); const theSymbols = getCurrencyCharacters(currencyISOCode); const theCurrDec = theSymbols.theDecimalIndicator; const theCurrSep = theSymbols.theDigitGroupSeparator; const theCurrSym = theSymbols.theCurrencySymbol; const theCurrencyOptions = getCurrencyOptions(currencyISOCode); useEffect(() => { setValues(value.toString()); }, [value]); let readOnlyProp = {}; // Note: empty if NOT ReadOnly if (readOnly) { readOnlyProp = { readOnly: true }; } let formattedValue = ''; if (formatter === 'Currency') { formattedValue = format(value, formatter.toLowerCase(), theCurrencyOptions); } else { formattedValue = format(value, pConn.getComponentName()?.toLowerCase(), theCurrencyOptions); } if (displayMode === 'DISPLAY_ONLY') { return ; } if (displayMode === 'STACKED_LARGE_VAL') { return ; } const testProps: any = { 'data-test-id': testId }; function decimalOnBlur() { handleEvent(actions, 'changeNblur', propName, values); } const handleChange = val => { setValues(val.value); }; return ( { handleChange(val); }} onBlur={!readOnly ? decimalOnBlur : undefined} prefix={readOnly && formatter === 'Currency' ? theCurrSym : ''} suffix={readOnly && formatter === 'Percentage' ? '%' : ''} decimalSeparator={theCurrDec} thousandSeparator={showGroupSeparators ? theCurrSep : ''} decimalScale={readOnly && formatter === 'Currency' ? undefined : decimalPrecision} slotProps={{ input: { ...readOnlyProp, inputProps: { ...testProps } } }} customInput={TextField} sx={getFieldSx(status)} /> ); }