import React, { useState, useEffect, useRef } from 'react' import VisualizationHeader from './VisualizationHeader' import BlankSlate from './ChartBlankSlate' import ErrorAlert from './ErrorAlert' import { theme, type Dataset, type QueryResultState, } from '@latitude-data/client' import { Card } from '$src/lib/ui' export type WrapperProps = QueryResultState & { bordered?: boolean title?: string description?: string height?: number width?: number download?: () => Promise className?: string children: (props: { dataset: Dataset contentHeight?: number }) => React.ReactNode } export default function ChartWrapper({ data, isLoading, error, bordered = false, title, description, height = 400, width, download, className, children, }: WrapperProps) { const cardStyle = bordered ? 'normal' : 'invisible' const dataset = { fields: data?.fields ? data.fields.map((f) => f.name) : [], source: data?.rows ?? [], } as Dataset const cardHeader = useRef(null) const cardContent = useRef(null) const [headerHeight, setHeaderHeight] = useState(0) useEffect(() => { if (!cardHeader.current) return const cs = window.getComputedStyle(cardHeader.current) const paddingTop = parseFloat(cs.paddingTop) const paddingBottom = parseFloat(cs.paddingBottom) const newHeaderHeight = cardHeader.current.clientHeight + paddingTop + paddingBottom setHeaderHeight(newHeaderHeight) }, [cardHeader, setHeaderHeight]) const [contentHeight, setContentHeight] = useState(height) useEffect(() => { if (!cardContent.current) return const cs = window.getComputedStyle(cardContent.current) const paddingTop = parseFloat(cs.paddingTop) const paddingBottom = parseFloat(cs.paddingBottom) const padding = paddingTop + paddingBottom let newContentHeight = undefined if (height) { newContentHeight = height - headerHeight + (title ? padding : -padding) } setContentHeight(newContentHeight) }, [title, height, headerHeight, setContentHeight]) return (
{error ? ( ) : !data || (!data && isLoading) ? ( ) : ( children({ dataset, contentHeight }) )}
) }