Skip to content

Commit f99474c

Browse files
authored
fix: token input decimals handling (#91)
1 parent 525d4d4 commit f99474c

9 files changed

Lines changed: 163 additions & 40 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@interlay/ui": patch
3+
---
4+
5+
fix: token input decimals handling

packages/components/src/TokenInput/BaseTokenInput.tsx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ const escapeRegExp = (string: string): string => {
2424
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
2525
};
2626

27+
const hasCorrectDecimals = (value: string, decimals: number) => {
28+
const decimalGroups = value.split('.');
29+
30+
return decimalGroups.length > 1 ? decimalGroups[1].length <= decimals : true;
31+
};
32+
2733
type Props = {
2834
valueUSD?: number;
2935
balance?: ReactNode;
@@ -33,8 +39,10 @@ type Props = {
3339
size?: TokenInputSize;
3440
isInvalid?: boolean;
3541
minHeight?: Spacing;
36-
value?: string | number;
37-
defaultValue?: string | number;
42+
value?: string;
43+
defaultValue?: string;
44+
// TODO: use Currency from bob-ui
45+
currency: { decimals: number };
3846
onValueChange?: (value: string | number) => void;
3947
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
4048
onFocus?: (e: FocusEvent<Element>) => void;
@@ -69,6 +77,7 @@ const BaseTokenInput = forwardRef<HTMLInputElement, BaseTokenInputProps>(
6977
inputMode,
7078
value: valueProp,
7179
endAdornment,
80+
currency,
7281
onChange,
7382
onValueChange,
7483
...props
@@ -84,9 +93,13 @@ const BaseTokenInput = forwardRef<HTMLInputElement, BaseTokenInputProps>(
8493
(e) => {
8594
const value = e.target.value;
8695

87-
const isValid = value === '' || RegExp(`^\\d*(?:\\\\[.])?\\d*$`).test(escapeRegExp(value));
96+
const isEmpty = value === '';
97+
const hasValidDecimalFormat = RegExp(`^\\d*(?:\\\\[.])?\\d*$`).test(escapeRegExp(value));
98+
const hasValidDecimalsAmount = hasCorrectDecimals(value, currency.decimals);
99+
100+
const isValid = hasValidDecimalFormat && hasValidDecimalsAmount;
88101

89-
if (isValid) {
102+
if (isEmpty || isValid) {
90103
onChange?.(e);
91104
onValueChange?.(value);
92105
setValue(value);

packages/components/src/TokenInput/FixedTokenInput.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { BaseTokenInput, BaseTokenInputProps } from './BaseTokenInput';
55
import { TokenInputBalance } from './TokenInputBalance';
66

77
type Props = {
8-
balance?: string | number;
8+
balance?: string;
99
humanBalance?: string | number;
1010
balanceLabel?: ReactNode;
1111
onClickBalance?: (balance: string | number) => void;

packages/components/src/TokenInput/SelectableTokenInput.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import { TokenInputBalance } from './TokenInputBalance';
88
import { TokenSelect, TokenSelectProps } from './TokenSelect';
99

1010
type Props = {
11-
balance?: string | number;
11+
balance?: string;
1212
humanBalance?: string | number;
1313
balanceLabel?: ReactNode;
14-
onClickBalance?: (balance: string | number) => void;
14+
onClickBalance?: (balance: string) => void;
1515
selectProps: Omit<TokenSelectProps, 'label' | 'helperTextId'>;
1616
};
1717

@@ -75,7 +75,7 @@ const SelectableTokenInput = forwardRef<HTMLInputElement, SelectableTokenInputPr
7575

7676
const balance = balanceProp !== undefined && (
7777
<TokenInputBalance
78-
balance={ticker ? balanceProp : 0}
78+
balance={ticker ? balanceProp : '0'}
7979
balanceHuman={humanBalance}
8080
inputId={id}
8181
isDisabled={isDisabled || !ticker}

packages/components/src/TokenInput/TokenInput.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { SelectableTokenInput, SelectableTokenInputProps } from './SelectableTok
77

88
type Props = {
99
onValueChange?: (value?: string | number) => void;
10+
// TODO: define type when repo moved to bob-ui
11+
currency: any;
1012
};
1113

1214
type FixedAttrs = Omit<FixedTokenInputProps, keyof Props>;
@@ -38,7 +40,7 @@ const TokenInput = forwardRef<HTMLInputElement, TokenInputProps>(
3840
setValue(value);
3941
};
4042

41-
const handleClickBalance = (balance: string | number) => {
43+
const handleClickBalance = (balance: string) => {
4244
inputRef.current?.focus();
4345
setValue(balance);
4446
onValueChange?.(balance);

packages/components/src/TokenInput/TokenInputBalance.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import { StyledBalance, StyledMaxButton } from './TokenInput.style';
66

77
type TokenInputBalanceProps = {
88
inputId?: string;
9-
balance: string | number;
9+
balance: string;
1010
balanceHuman?: string | number;
11-
onClickBalance?: (balance: string | number) => void;
11+
onClickBalance?: (balance: string) => void;
1212
isDisabled?: boolean;
1313
label?: ReactNode;
1414
};
@@ -21,7 +21,7 @@ const TokenInputBalance = ({
2121
isDisabled: isDisabledProp,
2222
label = 'Balance'
2323
}: TokenInputBalanceProps): JSX.Element => {
24-
const isDisabled = isDisabledProp || balanceProp === 0;
24+
const isDisabled = isDisabledProp || Number(balanceProp) === 0;
2525

2626
const ariaLabel = typeof label === 'string' ? `apply max ${label}` : 'apply max';
2727

0 commit comments

Comments
 (0)