diff --git a/app/components/chart-footnotes.tsx b/app/components/chart-footnotes.tsx index 55ac6181f..d9e35923b 100644 --- a/app/components/chart-footnotes.tsx +++ b/app/components/chart-footnotes.tsx @@ -49,20 +49,23 @@ export const ChartFootnotes = ({ dataSource, chartConfig, configKey, + onToggleTableView, }: { dataSetIri: string; dataSource: DataSource; chartConfig: ChartConfig; configKey?: string; + onToggleTableView: () => void; }) => { const classes = useStyles(); const locale = useLocale(); const [shareUrl, setShareUrl] = useState(""); - const [isChartTablePreview, setIsChartTablePreview] = useChartTablePreview(); + const { state: isTablePreview, setState: setIsTablePreview } = + useChartTablePreview(); // Reset back to chart view when switching chart type. useEffect(() => { - setIsChartTablePreview(false); - }, [setIsChartTablePreview, chartConfig.chartType]); + setIsTablePreview(false); + }, [setIsTablePreview, chartConfig.chartType]); useEffect(() => { setShareUrl(`${window.location.origin}/${locale}/v/${configKey}`); @@ -144,16 +147,16 @@ export const ChartFootnotes = ({ startIcon={ } - onClick={() => setIsChartTablePreview(!isChartTablePreview)} + onClick={onToggleTableView} sx={{ p: 0, typography: "caption" }} > - {isChartTablePreview ? ( + {isTablePreview ? ( Switch to chart view ) : ( Switch to table view diff --git a/app/components/chart-preview.tsx b/app/components/chart-preview.tsx index a4fa6a47a..26413a5c4 100644 --- a/app/components/chart-preview.tsx +++ b/app/components/chart-preview.tsx @@ -23,7 +23,7 @@ import { DataSetTable } from "@/configurator/components/datatable"; import { useDataCubeMetadataQuery } from "@/graphql/query-hooks"; import { DataCubePublicationStatus } from "@/graphql/resolver-types"; import { useLocale } from "@/locales/use-locale"; -import { useResizeObserver } from "@/utils/use-resize-observer"; +import useEvent from "@/utils/use-event"; export const ChartPreview = ({ dataSetIri, @@ -57,16 +57,14 @@ export const ChartPreviewInner = ({ locale, }, }); - const [isTablePreview] = useChartTablePreview(); + const { + state: isTablePreview, + setState: setIsTablePreview, + containerRef, + containerHeight, + } = useChartTablePreview(); - const [chartRef, _, height] = useResizeObserver(); - const lastHeight = React.useRef(height); - - React.useEffect(() => { - if (height !== 0) { - lastHeight.current = height; - } - }, [height]); + const handleToggleTableView = useEvent(() => setIsTablePreview((c) => !c)); return ( - {isTablePreview ? ( - - ) : ( - - )} + + {isTablePreview ? ( + + ) : ( + + )} + {state.chartConfig && ( )} diff --git a/app/components/chart-published.tsx b/app/components/chart-published.tsx index 77c259fd3..3f975631c 100644 --- a/app/components/chart-published.tsx +++ b/app/components/chart-published.tsx @@ -35,7 +35,7 @@ import { import { useDataCubeMetadataQuery } from "@/graphql/query-hooks"; import { DataCubePublicationStatus } from "@/graphql/resolver-types"; import { useLocale } from "@/locales/use-locale"; -import { useResizeObserver } from "@/utils/use-resize-observer"; +import useEvent from "@/utils/use-event"; export const ChartPublished = ({ dataSet, @@ -100,16 +100,6 @@ export const ChartPublishedInner = ({ locale, }, }); - const [isTablePreview] = useChartTablePreview(); - - const [chartRef, _, height] = useResizeObserver(); - const lastHeight = React.useRef(height); - - React.useEffect(() => { - if (height !== 0) { - lastHeight.current = height; - } - }, [height]); const publishedConfiguratorState = useMemo(() => { return { @@ -119,6 +109,14 @@ export const ChartPublishedInner = ({ } as ConfiguratorStatePublishing; }, [chartConfig, dataSource]); + const { + state: isTablePreview, + setState: setIsTablePreview, + containerRef, + containerHeight, + } = useChartTablePreview(); + const handleToggleTableView = useEvent(() => setIsTablePreview((c) => !c)); + return ( @@ -175,7 +173,7 @@ export const ChartPublishedInner = ({ )} - + ) : ( )} diff --git a/app/components/chart-table-preview.tsx b/app/components/chart-table-preview.tsx index 613437fdb..ba6afbdef 100644 --- a/app/components/chart-table-preview.tsx +++ b/app/components/chart-table-preview.tsx @@ -2,13 +2,28 @@ import { createContext, Dispatch, ReactNode, + SetStateAction, useContext, useState, + useCallback, + useRef, + useMemo, + RefObject, } from "react"; -const ChartTablePreviewContext = createContext< - [boolean, Dispatch] | undefined ->(undefined); +type Context = { + state: boolean; + setState: Dispatch>; + containerRef: RefObject; + containerHeight: RefObject<"auto" | number>; +}; + +const ChartTablePreviewContext = createContext({ + state: true, + setState: () => {}, + containerRef: { current: null }, + containerHeight: { current: "auto" }, +}); export const useChartTablePreview = () => { const ctx = useContext(ChartTablePreviewContext); @@ -22,15 +37,41 @@ export const useChartTablePreview = () => { return ctx; }; +/** + * Keep tracks of whether we are looking at the chart of a table + * Before changing type, the height of containerRef is measured + * and passed back into containerHeight. + */ export const ChartTablePreviewProvider = ({ children, }: { children: ReactNode; }) => { - const [state, dispatch] = useState(false); + const [state, setStateRaw] = useState(false); + const containerHeight = useRef("auto" as "auto" | number); + const containerRef = useRef(null); + const setState = useCallback( + (v) => { + if (!containerRef.current) { + return; + } + const bcr = containerRef.current.getBoundingClientRect(); + containerHeight.current = bcr.height; + return setStateRaw(v); + }, + [setStateRaw] + ); + const ctx = useMemo(() => { + return { + state, + setState, + containerRef, + containerHeight, + }; + }, [setState, state]); return ( - + {children} );