-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: amount input hook and component
- Loading branch information
1 parent
41e2585
commit 09ca26c
Showing
7 changed files
with
107 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
packages/react-components/src/lib/components/AmountInput.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import React, { type Ref, forwardRef } from 'react'; | ||
import type { NatValue } from '@agoric/ertp/src/types'; | ||
import { useAmountInput } from '../hooks/amountInput.js'; | ||
|
||
const noop = () => { | ||
/* no-op */ | ||
}; | ||
|
||
type Props = { | ||
value: NatValue | null; | ||
decimalPlaces: number; | ||
className?: React.HtmlHTMLAttributes<HTMLInputElement>['className']; | ||
onChange?: (value: NatValue) => void; | ||
disabled?: boolean; | ||
}; | ||
|
||
const RenderAmountInput = ( | ||
{ value, decimalPlaces, className, onChange = noop, disabled = false }: Props, | ||
ref?: Ref<HTMLInputElement>, | ||
) => { | ||
const { displayString, handleInputChange } = useAmountInput({ | ||
value, | ||
decimalPlaces, | ||
onChange, | ||
}); | ||
|
||
return ( | ||
<input | ||
className={className} | ||
type="number" | ||
placeholder="0" | ||
min="0" | ||
disabled={disabled} | ||
value={displayString} | ||
onChange={handleInputChange} | ||
ref={ref} | ||
/> | ||
); | ||
}; | ||
|
||
export const AmountInput = forwardRef(RenderAmountInput); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from './ConnectWalletButton'; | ||
export * from './NodeSelectorModal'; | ||
export * from './AmountInput'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { useContext } from 'react'; | ||
import { AgoricContext } from '../context'; | ||
|
||
export const useAgoric = () => useContext(AgoricContext); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import type { NatValue } from '@agoric/ertp/src/types'; | ||
import { AssetKind } from '@agoric/ertp'; | ||
import { parseAsValue, stringifyValue } from '@agoric/web-components'; | ||
import { useState } from 'react'; | ||
|
||
type Args = { | ||
value: NatValue | null; | ||
decimalPlaces: number; | ||
onChange: (value: NatValue) => void; | ||
}; | ||
|
||
export const useAmountInput = ({ value, decimalPlaces, onChange }: Args) => { | ||
const amountString = stringifyValue(value, AssetKind.NAT, decimalPlaces); | ||
|
||
const [fieldString, setFieldString] = useState( | ||
value === null ? '' : amountString, | ||
); | ||
|
||
const handleInputChange: React.ChangeEventHandler<HTMLInputElement> = ev => { | ||
// Inputs with type "number" allow these characters which don't apply to | ||
// Amounts, just strip them. | ||
const str = ev.target?.value | ||
?.replace('-', '') | ||
.replace('e', '') | ||
.replace('E', ''); | ||
setFieldString(str); | ||
|
||
try { | ||
const parsed = parseAsValue(str, AssetKind.NAT, decimalPlaces); | ||
onChange(parsed); | ||
} catch { | ||
console.debug('Invalid input', str); | ||
} | ||
}; | ||
|
||
// Use the `fieldString` as an input buffer so the user can type values that | ||
// would be overwritten by `stringifyValue`. For example, if the current | ||
// input is "1.05", and you tried to change it to "1.25", on hitting | ||
// backspace, `stringifyValue` would change it from "1.0" to "1.00", | ||
// preventing you from ever editing it. Only let `amountString` override | ||
// `fieldString` if the controlled input is trying to change it to a truly | ||
// different value. | ||
const displayString = | ||
value === parseAsValue(fieldString, AssetKind.NAT, decimalPlaces) | ||
? fieldString | ||
: amountString; | ||
|
||
return { displayString, handleInputChange }; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,2 @@ | ||
import { useContext } from 'react'; | ||
import { AgoricContext } from '../context'; | ||
|
||
export const useAgoric = () => useContext(AgoricContext); | ||
export * from './agoric.js'; | ||
export * from './amountInput.js'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6586,10 +6586,10 @@ | |
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" | ||
integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== | ||
|
||
"@types/[email protected].7": | ||
version "18.2.7" | ||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.7.tgz#67222a08c0a6ae0a0da33c3532348277c70abb63" | ||
integrity sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA== | ||
"@types/[email protected].20": | ||
version "18.2.20" | ||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.20.tgz#cbdf7abb3cc2377980bb1294bc51375016a8320f" | ||
integrity sha512-HXN/biJY8nv20Cn9ZbCFq3liERd4CozVZmKbaiZ9KiKTrWqsP7eoGDO6OOGvJQwoVFuiXaiJ7nBBjiFFbRmQMQ== | ||
dependencies: | ||
"@types/react" "*" | ||
|
||
|
@@ -6609,10 +6609,10 @@ | |
"@types/scheduler" "*" | ||
csstype "^3.0.2" | ||
|
||
"@types/[email protected].20": | ||
version "18.2.20" | ||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.20.tgz#1605557a83df5c8a2cc4eeb743b3dfc0eb6aaeb2" | ||
integrity sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw== | ||
"@types/[email protected].63": | ||
version "18.2.63" | ||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.63.tgz#4637c56146ad90f96d0583171edab953f7e6fe57" | ||
integrity sha512-ppaqODhs15PYL2nGUOaOu2RSCCB4Difu4UFrP4I3NHLloXC/ESQzQMi9nvjfT1+rudd0d2L3fQPJxRSey+rGlQ== | ||
dependencies: | ||
"@types/prop-types" "*" | ||
"@types/scheduler" "*" | ||
|