mirror of
https://github.com/minibits-cash/minibits_wallet.git
synced 2026-10-05 19:28:26 +00:00
100 lines
2.8 KiB
TypeScript
100 lines
2.8 KiB
TypeScript
import React, { forwardRef, useState } from 'react'
|
|
import { TextInput, TextStyle } from 'react-native'
|
|
import { spacing, useThemeColor, typography } from '../theme'
|
|
import { verticalScale } from '@gocodingnow/rn-size-matters'
|
|
import { MintUnit, getCurrency } from '../services/wallet/currency'
|
|
import numbro from 'numbro'
|
|
|
|
interface AmountInputProps {
|
|
value: string
|
|
onChangeText: (text: string) => void
|
|
unit?: MintUnit
|
|
/**
|
|
* Override default formatting options (thousandSeparated, mantissa, etc.) for onEndEditing formatting.
|
|
* Useful for fiat currencies that need custom decimal precision or thousand separator behavior.
|
|
*/
|
|
formatOptions?: Partial<numbro.Format>
|
|
onEndEditing?: () => void
|
|
editable?: boolean
|
|
selectTextOnFocus?: boolean
|
|
onFocus?: () => void
|
|
onBlur?: () => void
|
|
style?: TextStyle
|
|
}
|
|
|
|
export const AmountInput = forwardRef<TextInput, AmountInputProps>(
|
|
(
|
|
{
|
|
value,
|
|
onChangeText,
|
|
unit = 'sat',
|
|
formatOptions,
|
|
onEndEditing,
|
|
editable = true,
|
|
selectTextOnFocus,
|
|
onFocus,
|
|
onBlur,
|
|
style,
|
|
...rest
|
|
},
|
|
ref
|
|
) => {
|
|
const [hasAmountFocusedOnce, setHasAmountFocusedOnce] = useState(false)
|
|
const amountInputColor = useThemeColor('amountInput')
|
|
|
|
const handleFocus = () => {
|
|
setHasAmountFocusedOnce(true)
|
|
onFocus?.()
|
|
}
|
|
|
|
const handleBlur = () => {
|
|
setHasAmountFocusedOnce(false)
|
|
onBlur?.()
|
|
}
|
|
|
|
const handleEndEditing = () => {
|
|
if (onEndEditing) onEndEditing();
|
|
if (!value) value = "0";
|
|
// ^^ needed as previous '=== undefined' check didn't trigger on value = "",
|
|
// which would still crash numbro's formatter
|
|
|
|
// Merge default format options with overrides
|
|
const formatOptionsMerged = Object.assign(
|
|
{ thousandSeparated: true, mantissa: getCurrency(unit).mantissa },
|
|
formatOptions
|
|
);
|
|
const formattedValue = numbro(value).format(formatOptionsMerged);
|
|
onChangeText(formattedValue)
|
|
}
|
|
|
|
const defaultStyle: TextStyle = {
|
|
borderRadius: spacing.small,
|
|
margin: 0,
|
|
padding: 0,
|
|
fontSize: verticalScale(48),
|
|
fontFamily: typography.primary?.medium,
|
|
textAlign: 'center',
|
|
color: amountInputColor,
|
|
}
|
|
|
|
return (
|
|
<TextInput
|
|
ref={ref}
|
|
value={value}
|
|
onChangeText={onChangeText}
|
|
onEndEditing={handleEndEditing}
|
|
onFocus={handleFocus}
|
|
onBlur={handleBlur}
|
|
style={[defaultStyle, style]}
|
|
maxLength={9}
|
|
keyboardType="numeric"
|
|
returnKeyType="done"
|
|
selectTextOnFocus={selectTextOnFocus !== undefined ? selectTextOnFocus : !hasAmountFocusedOnce}
|
|
editable={editable}
|
|
{...rest}
|
|
/>
|
|
)
|
|
}
|
|
)
|
|
|
|
AmountInput.displayName = 'AmountInput' |