diff --git a/src/components/Balance.module.css b/src/components/Balance.module.css
index ced0b163..013532ec 100644
--- a/src/components/Balance.module.css
+++ b/src/components/Balance.module.css
@@ -22,23 +22,35 @@
color: var(--jam-balance-color);
}
-.frozenSymbol {
- order: -2;
+.hideSymbol {
+ padding-left: 0.1em;
+ color: var(--jam-balance-deemphasize-color);
}
.bitcoinSymbol {
- padding-right: 0.1em;
order: -1;
+ width: 1em;
+ padding-right: 0.1em;
}
.satsSymbol {
- padding-right: 0.1em;
- order: 6;
+ order: 5;
}
-.hideSymbol {
- padding-left: 0.1em;
- color: var(--jam-balance-deemphasize-color);
+.frozenSymbol {
+ order: 5;
+}
+.bitcoinAmount + .frozenSymbol {
+ order: -2;
+ width: 1em;
+ height: 1em;
+}
+
+.frozenSymbol,
+.bitcoinSymbol,
+.satsSymbol {
+ display: flex;
+ justify-content: center;
}
.bitcoinAmount .fractionalPart :nth-child(3)::before,
diff --git a/src/components/Balance.test.tsx b/src/components/Balance.test.tsx
index 9429387c..68377b10 100644
--- a/src/components/Balance.test.tsx
+++ b/src/components/Balance.test.tsx
@@ -11,31 +11,46 @@ describe('', () => {
expect(screen.getByText(`NaN`)).toBeInTheDocument()
})
- it('should render BTC using satscomma formatting', () => {
+ it('should render balance in BTC', () => {
render()
expect(screen.getByTestId('bitcoin-amount').dataset.formattedValue).toBe(`123.45600000`)
+ expect(screen.getByTestId('bitcoin-symbol')).toBeVisible()
+ expect(screen.queryByTestId('sats-symbol')).not.toBeInTheDocument()
+ expect(screen.queryByTestId('frozen-symbol')).not.toBeInTheDocument()
+ })
+
+ it('should render balance in SATS', () => {
+ render()
+ expect(screen.getByTestId('sats-amount')).toHaveTextContent(`12,345,600,000`)
+ expect(screen.getByTestId('sats-symbol')).toBeVisible()
+ expect(screen.queryByTestId('bitcoin-symbol')).not.toBeInTheDocument()
+ expect(screen.queryByTestId('frozen-symbol')).not.toBeInTheDocument()
})
it('should hide balance for BTC by default', () => {
render()
expect(screen.getByText(`*****`)).toBeInTheDocument()
expect(screen.queryByTestId('bitcoin-amount')).not.toBeInTheDocument()
+ expect(screen.queryByTestId('bitcoin-symbol')).not.toBeInTheDocument()
})
it('should hide balance for SATS by default', () => {
render()
expect(screen.getByText(`*****`)).toBeInTheDocument()
expect(screen.queryByTestId(`sats-amount`)).not.toBeInTheDocument()
+ expect(screen.queryByTestId('sats-symbol')).not.toBeInTheDocument()
})
it('should render a string BTC value correctly as BTC', () => {
render()
expect(screen.getByTestId('bitcoin-amount').dataset.formattedValue).toBe(`123.03224961`)
+ expect(screen.getByTestId('bitcoin-symbol')).toBeVisible()
})
it('should render a string BTC value correctly as SATS', () => {
render()
expect(screen.getByTestId(`sats-amount`)).toHaveTextContent(`12,303,224,961`)
+ expect(screen.getByTestId('sats-symbol')).toBeVisible()
})
it('should render a zero string BTC value correctly as BTC', () => {
@@ -108,6 +123,27 @@ describe('', () => {
expect(screen.getByTestId(`sats-amount`)).toHaveTextContent(`2,100,000,000,000,000`)
})
+ it('should render frozen balance in BTC', () => {
+ render()
+ expect(screen.getByTestId('bitcoin-amount').dataset.formattedValue).toBe(`123.45600000`)
+ expect(screen.getByTestId('bitcoin-symbol')).toBeVisible()
+ expect(screen.getByTestId('frozen-symbol')).toBeVisible()
+ })
+
+ it('should render frozen balance in SATS', () => {
+ render()
+ expect(screen.getByTestId('sats-amount')).toHaveTextContent(`12,345,600,000`)
+ expect(screen.getByTestId('sats-symbol')).toBeVisible()
+ 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 9d494375..880d0f67 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, useEffect, useMemo, useState } from 'react'
import classNames from 'classnames'
import Sprite from './Sprite'
import { SATS, BTC, btcToSats, satsToBtc, isValidNumber, formatBtc, formatSats } from '../utils'
@@ -15,74 +15,99 @@ 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'}
+const BTC_SYMBOL = (
+
+ {'\u20BF'}
+
+)
-const SAT_SYMBOL =
+const SAT_SYMBOL = (
+
+)
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 (
+ {children}
+ {showSymbol && symbol}
{frozen && FROZEN_SYMBOL}
- {value}
- {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.
*
@@ -97,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
}
/**
@@ -113,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])
@@ -122,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.
@@ -151,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}>
diff --git a/src/components/jars/Jar.module.css b/src/components/jars/Jar.module.css
index b24d8b0a..9cb838df 100644
--- a/src/components/jars/Jar.module.css
+++ b/src/components/jars/Jar.module.css
@@ -58,10 +58,6 @@
font-size: 0.8rem;
}
-.frozen.jarBalance {
- font-size: 0.7rem;
-}
-
.selectableJarContainer {
display: flex;
flex-direction: column;
diff --git a/src/components/jars/Jar.tsx b/src/components/jars/Jar.tsx
index 4def150e..5b2fae67 100644
--- a/src/components/jars/Jar.tsx
+++ b/src/components/jars/Jar.tsx
@@ -135,6 +135,7 @@ const Jar = ({ index, balance, frozenBalance, fillLevel, isOpen = false }: JarPr
convertToUnit={settings.unit}
showBalance={settings.showBalance}
frozen={true}
+ showSymbol={false}
/>
)}