| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 |
- "use client";
- import { type ComponentRenderProps } from "@json-render/react";
- import { useData } from "@json-render/react";
- import { getByPath } from "@json-render/core";
- export function Metric({ element }: ComponentRenderProps) {
- const { label, valuePath, format, trend, trendValue } = element.props as {
- label: string;
- valuePath: string;
- format?: string | null;
- trend?: string | null;
- trendValue?: string | null;
- };
- const { data } = useData();
- const rawValue = getByPath(data, valuePath);
- let displayValue = String(rawValue ?? "-");
- if (format === "currency" && typeof rawValue === "number") {
- displayValue = new Intl.NumberFormat("en-US", {
- style: "currency",
- currency: "USD",
- }).format(rawValue);
- } else if (format === "percent" && typeof rawValue === "number") {
- displayValue = new Intl.NumberFormat("en-US", {
- style: "percent",
- minimumFractionDigits: 1,
- }).format(rawValue);
- } else if (format === "number" && typeof rawValue === "number") {
- displayValue = new Intl.NumberFormat("en-US").format(rawValue);
- }
- return (
- <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
- <span style={{ fontSize: 14, color: "var(--muted)" }}>{label}</span>
- <span style={{ fontSize: 32, fontWeight: 600 }}>{displayValue}</span>
- {(trend || trendValue) && (
- <span
- style={{
- fontSize: 14,
- color:
- trend === "up"
- ? "#22c55e"
- : trend === "down"
- ? "#ef4444"
- : "var(--muted)",
- }}
- >
- {trend === "up" ? "+" : trend === "down" ? "-" : ""}
- {trendValue}
- </span>
- )}
- </div>
- );
- }
|