| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- "use client";
- import { type ComponentRenderProps } from "@json-render/react";
- import { useData } from "@json-render/react";
- import { getByPath } from "@json-render/core";
- export function Table({ element }: ComponentRenderProps) {
- const { title, dataPath, columns } = element.props as {
- title?: string | null;
- dataPath: string;
- columns: Array<{ key: string; label: string; format?: string | null }>;
- };
- const { data } = useData();
- const tableData = getByPath(data, dataPath) as
- | Array<Record<string, unknown>>
- | undefined;
- if (!tableData || !Array.isArray(tableData)) {
- return <div style={{ padding: 20, color: "var(--muted)" }}>No data</div>;
- }
- const formatCell = (value: unknown, format?: string | null) => {
- if (value === null || value === undefined) return "-";
- if (format === "currency" && typeof value === "number") {
- return new Intl.NumberFormat("en-US", {
- style: "currency",
- currency: "USD",
- }).format(value);
- }
- if (format === "date" && typeof value === "string") {
- return new Date(value).toLocaleDateString();
- }
- if (format === "badge") {
- return (
- <span
- style={{
- padding: "2px 8px",
- borderRadius: 12,
- fontSize: 12,
- fontWeight: 500,
- background: "var(--border)",
- color: "var(--foreground)",
- }}
- >
- {String(value)}
- </span>
- );
- }
- return String(value);
- };
- return (
- <div>
- {title && (
- <h4 style={{ margin: "0 0 16px", fontSize: 14, fontWeight: 600 }}>
- {title}
- </h4>
- )}
- <table style={{ width: "100%", borderCollapse: "collapse" }}>
- <thead>
- <tr>
- {columns.map((col) => (
- <th
- key={col.key}
- style={{
- textAlign: "left",
- padding: "12px 8px",
- borderBottom: "1px solid var(--border)",
- fontSize: 12,
- fontWeight: 500,
- color: "var(--muted)",
- textTransform: "uppercase",
- letterSpacing: "0.05em",
- }}
- >
- {col.label}
- </th>
- ))}
- </tr>
- </thead>
- <tbody>
- {tableData.map((row, i) => (
- <tr key={i}>
- {columns.map((col) => (
- <td
- key={col.key}
- style={{
- padding: "12px 8px",
- borderBottom: "1px solid var(--border)",
- fontSize: 14,
- }}
- >
- {formatCell(row[col.key], col.format)}
- </td>
- ))}
- </tr>
- ))}
- </tbody>
- </table>
- </div>
- );
- }
|