Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/app/solve/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ import { useAcceptIntent } from "@/hooks/useAcceptIntent";
import { useSolverRegistration } from "@/hooks/useSolverRegistration";
import { timeRemaining } from "@/lib/time";
import { isValidStellarPublicKey } from "@/lib/stellarAddress";
import { formatCurrency } from "@/lib/format";

const usdCompact = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
const usdCompact = (value: number) => formatCurrency(value, undefined, {
notation: "compact",
maximumFractionDigits: 1,
});
Expand Down Expand Up @@ -163,6 +162,8 @@ export default function SolvePage() {
<div className="eyebrow text-[10px] sm:text-xs">Fills</div>
</div>
<div>
<div className="num text-sm font-semibold text-vx-text">{usdCompact(s.volumeUsd)}</div>
<div className="eyebrow">Volume</div>
<div className="num text-xs sm:text-sm font-semibold text-vx-text">{usdCompact.format(s.volumeUsd)}</div>
<div className="eyebrow text-[10px] sm:text-xs">Volume</div>
</div>
Expand Down
10 changes: 9 additions & 1 deletion src/components/SwapCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useQuote } from "@/hooks/useQuote";
import { useDebouncedValue } from "@/hooks/useDebouncedValue";
import { useSwapSubmission } from "@/hooks/useSwapSubmission";
import { CHAINS, SRC_TOKENS, DST_TOKENS } from "@/lib/marketData";
import { formatCurrency, formatTokenAmount } from "@/lib/format";
import { useTranslation } from "@/lib/i18n/I18nProvider";
import type { MessageKey } from "@/lib/i18n";

Expand Down Expand Up @@ -150,6 +151,8 @@ export function SwapCard() {
className={`w-full flex items-center justify-between px-3 py-2 rounded-lg text-sm transition-colors
${token.symbol === srcToken.symbol ? "bg-vx-lav-bg text-vx-lav" : "hover:bg-vx-surface text-vx-muted hover:text-vx-text"}`}
>
<span className="font-medium">{t.symbol}</span>
<span className="num text-xs">{formatCurrency(t.priceUSD)}</span>
<span className="font-medium">{token.symbol}</span>
<span className="num text-xs">${token.priceUSD.toLocaleString()}</span>
</button>
Expand All @@ -159,6 +162,7 @@ export function SwapCard() {

{srcValueUSD > 0 && (
<div className="num text-xs text-vx-muted">
≈ {formatCurrency(srcValueUSD, undefined, { maximumFractionDigits: 2 })}
{/* Number formatting stays locale-hardcoded here; issue #63 owns making it locale-aware. */}
{t("swap.from.approxValue", {
value: srcValueUSD.toLocaleString("en-US", { maximumFractionDigits: 2 }),
Expand Down Expand Up @@ -197,7 +201,11 @@ export function SwapCard() {
</div>
) : (
<div className="text-3xl font-light text-vx-text num">
{dstAmount > 0 ? dstAmount.toFixed(dstToken.symbol === "XLM" ? 2 : 4) : "0"}
{dstAmount > 0
? formatTokenAmount(dstAmount, undefined, {
maximumFractionDigits: dstToken.symbol === "XLM" ? 2 : 4,
})
: "0"}
</div>
)}
</div>
Expand Down
22 changes: 22 additions & 0 deletions src/lib/format.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { describe, expect, it } from "vitest";
import { formatCurrency, formatTokenAmount } from "./format";

describe("formatCurrency", () => {
it("formats USD values for en-US locale", () => {
expect(formatCurrency(1234.5, "en-US")).toBe("$1,234.50");
});

it("formats USD values for de-DE locale", () => {
expect(formatCurrency(1234.5, "de-DE")).toBe("1.234,50 $");
});
});

describe("formatTokenAmount", () => {
it("formats token amounts for en-US locale", () => {
expect(formatTokenAmount(1234.5678, "en-US", { maximumFractionDigits: 4 })).toBe("1,234.5678");
});

it("formats token amounts for de-DE locale", () => {
expect(formatTokenAmount(1234.5678, "de-DE", { maximumFractionDigits: 4 })).toBe("1.234,5678");
});
});
23 changes: 23 additions & 0 deletions src/lib/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const DEFAULT_LOCALE = "en-US";

function resolveLocale(locale?: string): string {
if (locale) return locale;

if (typeof navigator !== "undefined" && navigator.language) {
return navigator.language;
}

return DEFAULT_LOCALE;
}

export function formatCurrency(value: number, locale?: string, options: Intl.NumberFormatOptions = {}) {
return new Intl.NumberFormat(resolveLocale(locale), {
style: "currency",
currency: "USD",
...options,
}).format(value);
}

export function formatTokenAmount(value: number, locale?: string, options: Intl.NumberFormatOptions = {}) {
return new Intl.NumberFormat(resolveLocale(locale), options).format(value);
}