UNPKG

react-native-chart-kit

Version:

Beautiful React Native charts for dashboards, reports, and data-rich mobile apps.

93 lines (92 loc) 4.03 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react"; import { View } from "react-native"; import { getScopedChartSelectionClearReason, shouldClearScopedChartSelection } from "./scope"; const ChartSelectionContext = createContext(undefined); export const ChartSelectionProvider = ({ children, dismissOnPressOutside = false, style }) => { const pendingDismissTimeoutRef = useRef(null); const [state, setState] = useState({ activeChartId: undefined, dismissRevision: 0 }); const cancelPendingOutsideDismiss = useCallback(() => { if (pendingDismissTimeoutRef.current) { clearTimeout(pendingDismissTimeoutRef.current); pendingDismissTimeoutRef.current = null; } }, []); const applyDismissSelection = useCallback(() => { setState((current) => ({ activeChartId: undefined, dismissRevision: current.dismissRevision + 1 })); }, []); const selectChart = useCallback((chartId) => { cancelPendingOutsideDismiss(); setState((current) => current.activeChartId === chartId ? current : { ...current, activeChartId: chartId }); }, [cancelPendingOutsideDismiss]); const dismissSelection = useCallback(() => { cancelPendingOutsideDismiss(); applyDismissSelection(); }, [applyDismissSelection, cancelPendingOutsideDismiss]); const scheduleOutsideDismiss = useCallback(() => { cancelPendingOutsideDismiss(); pendingDismissTimeoutRef.current = setTimeout(() => { pendingDismissTimeoutRef.current = null; applyDismissSelection(); }, 0); }, [applyDismissSelection, cancelPendingOutsideDismiss]); const handleStartShouldSetResponderCapture = useCallback((_event) => { scheduleOutsideDismiss(); return false; }, [scheduleOutsideDismiss]); useEffect(() => cancelPendingOutsideDismiss, [cancelPendingOutsideDismiss]); const value = useMemo(() => ({ ...state, dismissSelection, selectChart }), [dismissSelection, selectChart, state]); return (_jsx(ChartSelectionContext.Provider, { value: value, children: dismissOnPressOutside ? (_jsx(View, { collapsable: false, onStartShouldSetResponderCapture: handleStartShouldSetResponderCapture, style: style, children: children })) : (children) })); }; export const useChartSelection = () => useContext(ChartSelectionContext); export const useDismissChartSelection = () => { const context = useChartSelection(); return useCallback((reason) => { context?.dismissSelection(reason); }, [context]); }; export const useScopedChartSelection = ({ chartId, controlled, hasSelection, onClear }) => { const context = useChartSelection(); const lastDismissRevisionRef = useRef(context?.dismissRevision ?? 0); useEffect(() => { if (!context) { return; } const lastDismissRevision = lastDismissRevisionRef.current; const shouldClear = !controlled && shouldClearScopedChartSelection({ activeChartId: context.activeChartId, chartId, dismissRevision: context.dismissRevision, hasSelection, lastDismissRevision }); lastDismissRevisionRef.current = context.dismissRevision; if (shouldClear) { onClear(getScopedChartSelectionClearReason({ activeChartId: context.activeChartId, chartId, dismissRevision: context.dismissRevision, lastDismissRevision }) ?? "programmatic"); } }, [chartId, context, controlled, hasSelection, onClear]); return useMemo(() => ({ dismissSelection: context?.dismissSelection, selectChart: () => { context?.selectChart(chartId); } }), [chartId, context]); };