diff --git a/src/components/Balance.test.tsx b/src/components/Balance.test.tsx index 58cd3471..68377b10 100644 --- a/src/components/Balance.test.tsx +++ b/src/components/Balance.test.tsx @@ -137,6 +137,13 @@ describe('', () => { expect(screen.getByTestId('frozen-symbol')).toBeVisible() }) + it('should render balance without symbol', () => { + render() + expect(screen.getByTestId('sats-amount')).toBeVisible() + expect(screen.getByTestId('frozen-symbol')).toBeVisible() + expect(screen.queryByTestId('sats-symbol')).not.toBeInTheDocument() + }) + it('should toggle visibility of initially hidden balance on click by default', () => { render() expect(screen.queryByTestId(`sats-amount`)).not.toBeInTheDocument() diff --git a/src/components/Balance.tsx b/src/components/Balance.tsx index 4eb67ed8..13f21723 100644 --- a/src/components/Balance.tsx +++ b/src/components/Balance.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useCallback, useEffect, useMemo, useState } from 'react' +import { PropsWithChildren, MouseEventHandler, useCallback, useEffect, useMemo, useState } from 'react' import classNames from 'classnames' import Sprite from './Sprite' import { SATS, BTC, btcToSats, satsToBtc, isValidNumber, formatBtc, formatSats } from '../utils' @@ -15,46 +15,6 @@ const getDisplayMode = (unit: Unit, showBalance: boolean) => { return DISPLAY_MODE_HIDDEN } -const DECIMAL_POINT_CHAR = '.' - -const BitcoinAmountComponent = ({ value }: { value: number }) => { - const numberString = formatBtc(value) - const [integerPart, fractionalPart] = numberString.split(DECIMAL_POINT_CHAR) - - const fractionPartArray = fractionalPart.split('') - const integerPartIsZero = integerPart === '0' - const fractionalPartStartsWithZero = fractionPartArray[0] === '0' - - return ( - - {integerPart} - {DECIMAL_POINT_CHAR} - - {fractionPartArray.map((digit, index) => ( - - {digit} - - ))} - - - ) -} - -const SatsAmountComponent = ({ value }: { value: number }) => { - return ( - - {formatSats(value)} - - ) -} - const BTC_SYMBOL = ( {'\u20BF'} @@ -76,12 +36,17 @@ const FROZEN_SYMBOL = ( ) interface BalanceComponentProps { - symbol: JSX.Element - value: JSX.Element + symbol?: JSX.Element + showSymbol?: boolean frozen?: boolean } -const BalanceComponent = ({ symbol, value, frozen = false }: BalanceComponentProps) => { +const BalanceComponent = ({ + symbol, + showSymbol = true, + frozen = false, + children, +}: PropsWithChildren) => { return ( {frozen && FROZEN_SYMBOL} - {value} - {symbol} + {children} + {showSymbol && symbol} ) } +const DECIMAL_POINT_CHAR = '.' + +type BitcoinBalanceProps = Omit & { value: number } + +const BitcoinBalance = ({ value, ...props }: BitcoinBalanceProps) => { + const numberString = formatBtc(value) + const [integerPart, fractionalPart] = numberString.split(DECIMAL_POINT_CHAR) + + const fractionPartArray = fractionalPart.split('') + const integerPartIsZero = integerPart === '0' + const fractionalPartStartsWithZero = fractionPartArray[0] === '0' + + return ( + + + {integerPart} + {DECIMAL_POINT_CHAR} + + {fractionPartArray.map((digit, index) => ( + + {digit} + + ))} + + + + ) +} + +type SatsBalanceProps = Omit & { value: number } + +const SatsBalance = ({ value, ...props }: SatsBalanceProps) => { + return ( + + + {formatSats(value)} + + + ) +} + /** * Options argument for Balance component. * @@ -109,12 +122,11 @@ const BalanceComponent = ({ symbol, value, frozen = false }: BalanceComponentPro * @param {loading}: A loading flag that renders a placeholder while true. * @param {enableVisibilityToggle}: A flag that controls whether the balance can mask/unmask when clicked */ -interface BalanceProps { +type BalanceProps = Omit & { valueString: string convertToUnit: Unit showBalance?: boolean enableVisibilityToggle?: boolean - frozen?: boolean } /** @@ -125,7 +137,7 @@ export default function Balance({ convertToUnit, showBalance = false, enableVisibilityToggle = !showBalance, - frozen = false, + ...props }: BalanceProps) { const [isBalanceVisible, setIsBalanceVisible] = useState(showBalance) const displayMode = useMemo(() => getDisplayMode(convertToUnit, isBalanceVisible), [convertToUnit, isBalanceVisible]) @@ -134,28 +146,29 @@ export default function Balance({ setIsBalanceVisible(showBalance) }, [showBalance]) - const toggleVisibility: MouseEventHandler = useCallback((e) => { + const toggleVisibility: MouseEventHandler = (e) => { e.preventDefault() e.stopPropagation() setIsBalanceVisible((current) => !current) - }, []) + } const balanceComponent = useMemo(() => { if (displayMode === DISPLAY_MODE_HIDDEN) { return ( } - value={{'*****'}} - frozen={frozen} - /> + {...props} + > + {'*****'} + ) } const valueNumber = parseFloat(valueString) if (!isValidNumber(valueNumber)) { console.warn(' component expects number input as string') - return } value={<>{valueString}} frozen={frozen} /> + return {valueString} } // Treat integers as sats. @@ -163,35 +176,17 @@ export default function Balance({ // Treat decimal numbers as btc. const valueIsBtc = !valueIsSats && valueString.indexOf('.') > -1 - if (valueIsBtc && displayMode === DISPLAY_MODE_BTC) - return ( - } frozen={frozen} /> - ) - if (valueIsSats && displayMode === DISPLAY_MODE_SATS) - return ( - } frozen={frozen} /> - ) + if (valueIsBtc && displayMode === DISPLAY_MODE_BTC) return + if (valueIsSats && displayMode === DISPLAY_MODE_SATS) return if (valueIsBtc && displayMode === DISPLAY_MODE_SATS) - return ( - } - frozen={frozen} - /> - ) + return if (valueIsSats && displayMode === DISPLAY_MODE_BTC) - return ( - } - frozen={frozen} - /> - ) + return console.warn(' component cannot determine balance format') - return } value={<>{valueString}} frozen={frozen} /> - }, [valueString, displayMode, frozen]) + return {valueString} + }, [valueString, displayMode, props]) if (!enableVisibilityToggle) { return <>{balanceComponent}