import React, { Context, ReactNode, createContext, useContext } from 'react' import { AnimationIteratees, CartesianScale, ScaleOrdinal, tuple, } from '../lib/types' import { SvgAttributes } from '../lib/types.svg' type ContextConsumer = (props: { children: (value: T) => ReactNode }) => JSX.Element function buildContext(): [ Context, () => T | null, ContextConsumer ] function buildContext( dependency: string ): [Context, () => T, ContextConsumer] function buildContext(dependency?: string) { const CurrentContext = createContext(null) const useHook = () => { const value = useContext(CurrentContext) if (value === null && dependency !== undefined) throw new Error(`${dependency} missing`) return value } const Consumer: ContextConsumer = ({ children }) => { const value = useHook() return <>{children(value)} } return tuple(CurrentContext, useHook, Consumer) } export const [ChartContext, useChartContext, ChartConsumer] = buildContext<{ width: number height: number top: number left: number right: number bottom: number }>('Chart') export const [GridContext, useGridContext, GridConsumer] = buildContext<{ xAxes: number yAxes: number xTicks: Array yTicks: Array }>('Grid') export const [StyleContext, useStyleContext, StyleConsumer] = buildContext() export const [AnimationContext, useAnimationContext, AnimationConsumer] = buildContext>() export const [CartesianContext, useCartesianContext, CartesianConsumer] = buildContext<{ xScale: CartesianScale yScale: CartesianScale /** @deprecated */ colorScale?: ScaleOrdinal }>('Cartesian') export type Mouse = { x: number y: number } export const [MouseContext, useMouseContext, MouseConsumer] = buildContext< Mouse | undefined >("Interaction missing (use 'interactive' prop)")