/* Copyright 2026 Marimo. All rights reserved. */ import React, { Suspense } from "react"; import { useLocale } from "react-aria"; import { LazyVegaEmbed } from "@/components/charts/lazy"; import { createBatchedLoader } from "@/plugins/impl/vega/batched"; import { useTheme } from "@/theme/useTheme"; import { logNever } from "@/utils/assertNever"; import { prettyDate } from "@/utils/dates"; import { prettyNumber, prettyScientificNumber } from "@/utils/numbers"; import { DelayMount } from "../../utils/delay-mount"; import { DatePopover } from "../date-popover"; import { ChartSkeleton } from "./chart-skeleton"; import { ColumnChartSpecModel } from "./chart-spec-model"; export const ColumnChartContext = React.createContext< ColumnChartSpecModel >(ColumnChartSpecModel.EMPTY); interface Props { columnId: string; } // We batch multiple calls to the same URL returning the same promise // for all calls with the same key. const batchedLoader = createBatchedLoader(); export const TableColumnSummary = ({ columnId, }: Props) => { const { locale } = useLocale(); const chartSpecModel = React.use(ColumnChartContext); const { theme } = useTheme(); const { spec, type, stats } = chartSpecModel.getHeaderSummary(columnId); let chart: React.ReactNode = null; if (spec) { const skeleton = ; chart = ( ); } const renderDate = ( date: string | number | null | undefined, type: "date" | "datetime", ) => { return ( {prettyDate(date, type, locale)} ); }; const renderStats = () => { if (!stats || type === undefined) { return null; } switch (type) { case "date": case "datetime": // Without a chart if (!spec) { return (
min: {renderDate(stats.min, type)} max: {renderDate(stats.max, type)} unique: {prettyNumber(stats.unique, locale)}
); } return (
{renderDate(stats.min, type)} {stats.min === stats.max ? null : ( -{renderDate(stats.max, type)} )}
); case "integer": case "number": // Without a chart if (!spec) { return (
min:{" "} {typeof stats.min === "number" ? prettyScientificNumber(stats.min, { shouldRound: true, locale, }) : stats.min} max:{" "} {typeof stats.max === "number" ? prettyScientificNumber(stats.max, { shouldRound: true, locale, }) : stats.max} unique: {prettyNumber(stats.unique, locale)}
); } // Numerical bar charts use built-in vega axis and ticks return null; case "boolean": // Without a chart if (!spec) { return (
true: {prettyNumber(stats.true, locale)} false: {prettyNumber(stats.false, locale)}
); } return null; case "time": return null; case "string": if (!spec) { return (
unique: {prettyNumber(stats.unique, locale)}
); } return null; case "unknown": return (
nulls: {prettyNumber(stats.nulls, locale)}
); default: logNever(type); return null; } }; return (
{chart} {renderStats()}
); };