style: enforce Vazirmatn-FD Persian digits across world economy, bonds and entire dashboard
This commit is contained in:
parent
d5dffd0980
commit
984d44a18b
|
|
@ -79,7 +79,12 @@ import { LmeView } from "@/components/LmeView";
|
|||
import { ImeView } from "@/components/ImeView";
|
||||
import { Building2 } from "lucide-react";
|
||||
|
||||
const API = API_BASE; // dev: "" (same-origin via Vite proxy); prod: VITE_API_BASE
|
||||
const API = API_BASE;
|
||||
|
||||
const faDigits = (s: string | number | null | undefined): string => {
|
||||
if (s == null) return "—";
|
||||
return String(s).replace(/[0-9]/g, (d) => "۰۱۲۳۴۵۶۷۸۹"[+d]);
|
||||
}; // dev: "" (same-origin via Vite proxy); prod: VITE_API_BASE
|
||||
|
||||
export const Route = createFileRoute("/dashboard")({
|
||||
head: () => ({
|
||||
|
|
@ -1365,8 +1370,7 @@ const STEEL_FLAGS: Record<string, string> = {
|
|||
"Saudi Arabia": "🇸🇦",
|
||||
};
|
||||
|
||||
// ASCII→Persian digits for any already-formatted string (keeps $ % T B . , # ▼ ▲)
|
||||
const faDigits = (s: string) => s.replace(/[0-9]/g, (d) => "۰۱۲۳۴۵۶۷۸۹"[+d]);
|
||||
// faDigits declared globally at top
|
||||
|
||||
const usd = (n: number, frac = 2) =>
|
||||
faDigits(n.toLocaleString("en-US", { minimumFractionDigits: frac, maximumFractionDigits: frac }));
|
||||
|
|
@ -2747,8 +2751,8 @@ function WorldEconomyView() {
|
|||
|
||||
const fmtCell = (col: (typeof WE_COLS)[number], val: number | null) => {
|
||||
if (val == null) return "—";
|
||||
if (col.gdp) return (val / 1000).toLocaleString("fa-IR", { maximumFractionDigits: 2 }) + " T$";
|
||||
return formatNumber(val) + (col.suffix || "");
|
||||
if (col.gdp) return faDigits((val / 1000).toFixed(2) + " T$");
|
||||
return faDigits(formatNumber(val) + (col.suffix || ""));
|
||||
};
|
||||
|
||||
const us10y = bonds.find((b) => b.code === "US10Y");
|
||||
|
|
@ -2851,12 +2855,12 @@ function WorldEconomyView() {
|
|||
</div>
|
||||
<div className="mt-2 flex items-baseline justify-between">
|
||||
<span className="text-2xl font-bold font-mono tabular-nums text-foreground">
|
||||
{us10y?.yield ? us10y.yield.toFixed(3) + "%" : "—"}
|
||||
{us10y?.yield ? faDigits(us10y.yield.toFixed(3) + "%") : "—"}
|
||||
</span>
|
||||
{us10y && <DeltaPill pct={us10y.change} dir={us10y.change >= 0 ? "up" : "down"} />}
|
||||
</div>
|
||||
<div className="mt-1 text-[11px] text-muted-foreground font-mono">
|
||||
تغییر: {us10y ? (us10y.change_abs >= 0 ? "+" : "") + (us10y.change_abs * 100).toFixed(1) + " bps" : "—"}
|
||||
تغییر: {us10y ? faDigits((us10y.change_abs >= 0 ? "+" : "") + (us10y.change_abs * 100).toFixed(1) + " bps") : "—"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -2867,12 +2871,12 @@ function WorldEconomyView() {
|
|||
</div>
|
||||
<div className="mt-2 flex items-baseline justify-between">
|
||||
<span className="text-2xl font-bold font-mono tabular-nums text-foreground">
|
||||
{de10y?.yield ? de10y.yield.toFixed(3) + "%" : "—"}
|
||||
{de10y?.yield ? faDigits(de10y.yield.toFixed(3) + "%") : "—"}
|
||||
</span>
|
||||
{de10y && <DeltaPill pct={de10y.change} dir={de10y.change >= 0 ? "up" : "down"} />}
|
||||
</div>
|
||||
<div className="mt-1 text-[11px] text-muted-foreground font-mono">
|
||||
تغییر: {de10y ? (de10y.change_abs >= 0 ? "+" : "") + (de10y.change_abs * 100).toFixed(1) + " bps" : "—"}
|
||||
تغییر: {de10y ? faDigits((de10y.change_abs >= 0 ? "+" : "") + (de10y.change_abs * 100).toFixed(1) + " bps") : "—"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -2883,12 +2887,12 @@ function WorldEconomyView() {
|
|||
</div>
|
||||
<div className="mt-2 flex items-baseline justify-between">
|
||||
<span className="text-2xl font-bold font-mono tabular-nums text-foreground">
|
||||
{gb10y?.yield ? gb10y.yield.toFixed(3) + "%" : "—"}
|
||||
{gb10y?.yield ? faDigits(gb10y.yield.toFixed(3) + "%") : "—"}
|
||||
</span>
|
||||
{gb10y && <DeltaPill pct={gb10y.change} dir={gb10y.change >= 0 ? "up" : "down"} />}
|
||||
</div>
|
||||
<div className="mt-1 text-[11px] text-muted-foreground font-mono">
|
||||
تغییر: {gb10y ? (gb10y.change_abs >= 0 ? "+" : "") + (gb10y.change_abs * 100).toFixed(1) + " bps" : "—"}
|
||||
تغییر: {gb10y ? faDigits((gb10y.change_abs >= 0 ? "+" : "") + (gb10y.change_abs * 100).toFixed(1) + " bps") : "—"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -2899,7 +2903,7 @@ function WorldEconomyView() {
|
|||
</div>
|
||||
<div className="mt-2 flex items-baseline justify-between">
|
||||
<span className={cn("text-2xl font-bold font-mono tabular-nums", (spread10_2 ?? 0) >= 0 ? "text-emerald-700" : "text-red-600")}>
|
||||
{spread10_2 != null ? (spread10_2 >= 0 ? "+" : "") + (spread10_2 * 100).toFixed(1) + " bps" : "—"}
|
||||
{spread10_2 != null ? faDigits((spread10_2 >= 0 ? "+" : "") + (spread10_2 * 100).toFixed(1) + " bps") : "—"}
|
||||
</span>
|
||||
<span className="text-[11px] px-2 py-0.5 rounded-full font-mono font-medium bg-muted text-muted-foreground">
|
||||
{(spread10_2 ?? 0) >= 0 ? "نرمال" : "وارونه (Inverted)"}
|
||||
|
|
@ -2943,28 +2947,28 @@ function WorldEconomyView() {
|
|||
</div>
|
||||
</td>
|
||||
<td className="p-3 text-center font-mono text-xs text-muted-foreground">
|
||||
<span className="px-2 py-0.5 rounded bg-muted/80">{b.tenor}</span>
|
||||
<span className="px-2 py-0.5 rounded bg-muted/80">{faDigits(b.tenor)}</span>
|
||||
</td>
|
||||
<td className="p-3 text-center font-mono font-bold text-base text-foreground tabular-nums">
|
||||
{b.yield != null ? b.yield.toFixed(3) + "%" : "—"}
|
||||
{b.yield != null ? faDigits(b.yield.toFixed(3) + "%") : "—"}
|
||||
</td>
|
||||
<td className="p-3 text-center font-mono text-xs tabular-nums">
|
||||
<DeltaPill pct={b.change} dir={isUp ? "up" : "down"} />
|
||||
</td>
|
||||
<td className="p-3 text-center font-mono text-xs tabular-nums text-foreground">
|
||||
{b.change_abs != null ? (b.change_abs >= 0 ? "+" : "") + (b.change_abs * 100).toFixed(1) : "—"}
|
||||
{b.change_abs != null ? faDigits((b.change_abs >= 0 ? "+" : "") + (b.change_abs * 100).toFixed(1)) : "—"}
|
||||
</td>
|
||||
<td className="p-3 text-center font-mono text-xs text-muted-foreground tabular-nums">
|
||||
{b.low != null && b.high != null ? `${b.low.toFixed(2)} - ${b.high.toFixed(2)}` : "—"}
|
||||
{b.low != null && b.high != null ? faDigits(`${b.low.toFixed(2)} - ${b.high.toFixed(2)}`) : "—"}
|
||||
</td>
|
||||
<td className={cn("p-3 text-center font-mono text-xs tabular-nums", (b.perf_w ?? 0) >= 0 ? "text-emerald-700" : "text-red-600")}>
|
||||
{b.perf_w != null ? (b.perf_w >= 0 ? "+" : "") + b.perf_w.toFixed(2) + "%" : "—"}
|
||||
{b.perf_w != null ? faDigits((b.perf_w >= 0 ? "+" : "") + b.perf_w.toFixed(2) + "%") : "—"}
|
||||
</td>
|
||||
<td className={cn("p-3 text-center font-mono text-xs tabular-nums", (b.perf_m ?? 0) >= 0 ? "text-emerald-700" : "text-red-600")}>
|
||||
{b.perf_m != null ? (b.perf_m >= 0 ? "+" : "") + b.perf_m.toFixed(2) + "%" : "—"}
|
||||
{b.perf_m != null ? faDigits((b.perf_m >= 0 ? "+" : "") + b.perf_m.toFixed(2) + "%") : "—"}
|
||||
</td>
|
||||
<td className={cn("p-3 text-center font-mono text-xs tabular-nums", (b.perf_y ?? 0) >= 0 ? "text-emerald-700" : "text-red-600")}>
|
||||
{b.perf_y != null ? (b.perf_y >= 0 ? "+" : "") + b.perf_y.toFixed(2) + "%" : "—"}
|
||||
{b.perf_y != null ? faDigits((b.perf_y >= 0 ? "+" : "") + b.perf_y.toFixed(2) + "%") : "—"}
|
||||
</td>
|
||||
<td className="p-3 text-center w-28">
|
||||
{b.sparkline && b.sparkline.length > 1 && (
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
@import "vazirmatn/misc/Farsi-Digits/Vazirmatn-FD-font-face.css";
|
||||
@import "vazirmatn/Vazirmatn-font-face.css";
|
||||
@import "tailwindcss" source(none);
|
||||
@source "../src";
|
||||
|
|
@ -257,8 +258,8 @@
|
|||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--font-sans: Vazirmatn, system-ui, sans-serif;
|
||||
--font-mono: Vazirmatn, system-ui, sans-serif;
|
||||
--font-sans: "Vazirmatn FD", Vazirmatn, system-ui, sans-serif;
|
||||
--font-mono: "Vazirmatn FD", Vazirmatn, system-ui, sans-serif;
|
||||
}
|
||||
|
||||
:root {
|
||||
|
|
@ -299,7 +300,7 @@
|
|||
@layer base {
|
||||
* { border-color: var(--color-border); }
|
||||
/* Unzoomable PWA: block double-tap zoom (pinch handled by the viewport meta) */
|
||||
html, body { font-family: var(--font-sans); touch-action: manipulation; }
|
||||
html, body { font-family: "Vazirmatn FD", Vazirmatn, system-ui, sans-serif; touch-action: manipulation; }
|
||||
body {
|
||||
background-color: var(--color-background);
|
||||
background-image:
|
||||
|
|
@ -312,12 +313,14 @@
|
|||
color: var(--color-foreground);
|
||||
direction: rtl;
|
||||
}
|
||||
/* Enforce Vazirmatn for all numbers, tabular-nums, and monospace elements */
|
||||
/* Enforce Vazirmatn with Persian digits for all numbers, tabular-nums, and monospace elements */
|
||||
.font-mono,
|
||||
.tabular-nums,
|
||||
span.font-mono,
|
||||
div.font-mono {
|
||||
font-family: Vazirmatn, system-ui, sans-serif !important;
|
||||
div.font-mono,
|
||||
td.tabular-nums,
|
||||
span.tabular-nums {
|
||||
font-family: "Vazirmatn FD", Vazirmatn, system-ui, sans-serif !important;
|
||||
font-feature-settings: "tnum" 1;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue