/* Copyright 2026 Marimo. All rights reserved. */ import { ChevronDownIcon, ChevronRightIcon } from "lucide-react"; import { useState } from "react"; import { useLocale } from "react-aria"; import { AddDataframeChart, renderChart, renderPreviewError, renderStats, } from "@/components/datasources/column-preview"; import { ColumnName, ColumnPreviewContainer, EmptyState, ErrorState, LoadingState, } from "@/components/datasources/components"; import { ErrorBoundary } from "@/components/editor/boundary/ErrorBoundary"; import { CopyClipboardIcon } from "@/components/icons/copy-icon"; import { Button } from "@/components/ui/button"; import { Command, CommandEmpty, CommandInput, CommandItem, CommandList, } from "@/components/ui/command"; import { Tooltip } from "@/components/ui/tooltip"; import type { DataType } from "@/core/kernel/messages"; import { useAsyncData } from "@/hooks/useAsyncData"; import type { PreviewColumn } from "@/plugins/impl/DataTablePlugin"; import { useTheme } from "@/theme/useTheme"; import { NAMELESS_COLUMN_PREFIX } from "../columns"; import { prettifyRowColumnCount } from "../pagination"; import { type FieldTypesWithExternalType, INDEX_COLUMN_NAME, SELECT_COLUMN_ID, } from "../types"; interface ColumnExplorerPanelProps { previewColumn: PreviewColumn; fieldTypes: FieldTypesWithExternalType | undefined | null; totalRows: number | "too_many"; totalColumns: number; tableId: string; } export const ColumnExplorerPanel = ({ previewColumn, fieldTypes, totalRows, totalColumns, tableId, }: ColumnExplorerPanelProps) => { const [searchValue, setSearchValue] = useState(""); const { locale } = useLocale(); const columns = fieldTypes?.filter(([columnName]) => { if ( columnName === SELECT_COLUMN_ID || columnName === INDEX_COLUMN_NAME || columnName.startsWith(NAMELESS_COLUMN_PREFIX) ) { return false; } return true; }); const filteredColumns = columns?.filter(([columnName]) => { return columnName.toLowerCase().includes(searchValue.toLowerCase()); }); return (
{prettifyRowColumnCount({ numRows: totalRows, totalColumns, locale })} columnName).join(",\n") || ""} className="h-3 w-3 ml-1 mt-0.5" /> setSearchValue(value)} /> No results. {filteredColumns?.map( ([columnName, [dataType, externalType]], index) => { return ( ); }, )}
); }; const ColumnItem = ({ columnName, dataType, externalType, previewColumn, defaultExpanded = false, }: { columnName: string; dataType: DataType; externalType: string; previewColumn: PreviewColumn; defaultExpanded?: boolean; }) => { const [isExpanded, setIsExpanded] = useState(defaultExpanded); const columnText = ( {columnName} ); return ( <> setIsExpanded(!isExpanded)} className="flex flex-row items-center gap-1.5 group w-full cursor-pointer" > {isExpanded ? ( ) : ( )}
{externalType}
{isExpanded && ( )} ); }; const ColumnPreview = ({ previewColumn, columnName, dataType, }: { previewColumn: PreviewColumn; columnName: string; dataType: DataType; }) => { const { theme } = useTheme(); const { locale } = useLocale(); const { data, error, isPending, refetch: refetchPreview, } = useAsyncData(async () => { const response = await previewColumn({ column: columnName }); return response; }, []); if (error) { return ; } if (isPending) { return ; } if (!data) { return ; } const { chart_spec, chart_code, error: previewError, missing_packages, stats, } = data; const errorState = previewError && renderPreviewError({ error: previewError, missingPackages: missing_packages, refetchPreview, }); const previewStats = stats && renderStats({ stats, dataType, locale }); const chart = chart_spec && renderChart(chart_spec, theme); const addDataframeChart = chart_code && ( ); return ( {errorState} {addDataframeChart} {chart} {previewStats} ); };