import * as React from 'react' import { Interpolation, SpringConfig } from '@react-spring/web' import { CurveFactory } from 'd3-shape' import { ComponentType } from 'react' export type DatumValue = string | number | Date export interface Dimensions { height: number width: number } export interface Point { x: number y: number } export interface AlignBox extends Dimensions, Point {} export type Margin = { bottom: number left: number right: number top: number } export type Box = Partial export type BoxAlign = | 'center' | 'top-left' | 'top' | 'top-right' | 'right' | 'bottom-right' | 'bottom' | 'bottom-left' | 'left' export const boxAlignments: BoxAlign[] export function alignBox(box: AlignBox, container: AlignBox, alignment: BoxAlign): [number, number] export type GetColor = (datum: T) => string export type Colors = string[] | string export interface ColorProps { colors?: Colors colorBy?: string | GetColor } /** * Required text properties + optional ones. */ export type TextStyle = { fontFamily: Exclude fontSize: Exclude fill: string outlineWidth: number outlineColor: string } & Partial export type CompleteTheme = { background: string text: TextStyle axis: { domain: { line: Partial } ticks: { line: Partial text: TextStyle } legend: { text: TextStyle } } grid: { line: Partial } crosshair: { line: { stroke: string strokeWidth: number strokeOpacity: number strokeDasharray: string } } legends: { hidden: { symbol: Partial<{ fill: string opacity: number }> text: TextStyle } title: { text: TextStyle } text: TextStyle ticks: { line: Partial text: TextStyle } } labels: { text: Partial } markers: { lineColor: string lineStrokeWidth: number textColor: string fontSize: string | 0 text: TextStyle } dots: { text: TextStyle } tooltip: { container: Partial basic: Partial chip: Partial table: Partial tableCell: Partial tableCellValue: Partial } annotations: { text: { fill: string outlineWidth: number outlineColor: string outlineOpacity: number } & Partial> link: { stroke: string strokeWidth: number outlineWidth: number outlineColor: string outlineOpacity: number } & Partial> outline: { stroke: string strokeWidth: number outlineWidth: number outlineColor: string outlineOpacity: number } & Partial> symbol: { fill: string outlineWidth: number outlineColor: string outlineOpacity: number } & Partial> } } /** * Required properties without inheritance. * * The theme supports defining styles at the top level * (for text for example), which are then used to populate * similar nested properties. * * For example `text` will be merged with `axis.ticks.text`, * we use this approach so that it's simpler to define global styles. */ export type ThemeWithoutInheritance = { background: CompleteTheme['background'] text: CompleteTheme['text'] axis: { domain: { line: CompleteTheme['axis']['domain']['line'] } ticks: { line: CompleteTheme['axis']['ticks']['line'] text: Partial } legend: Partial<{ text: Partial }> } grid: { line: CompleteTheme['grid']['line'] } crosshair: { line: CompleteTheme['crosshair']['line'] } legends: { hidden: { symbol: CompleteTheme['legends']['hidden']['symbol'] text: Partial } title: { text: Partial } text: Partial ticks: { line: CompleteTheme['legends']['ticks']['line'] text: Partial } } labels: { text: Partial } markers: Partial dots: { text: Partial } tooltip: CompleteTheme['tooltip'] annotations: { text: Partial link: CompleteTheme['annotations']['link'] outline: CompleteTheme['annotations']['outline'] symbol: CompleteTheme['annotations']['symbol'] } } export type Theme = Partial<{ background: CompleteTheme['background'] text: Partial axis: Partial<{ domain: Partial<{ line: Partial }> ticks: Partial<{ line: Partial text: Partial }> legend: Partial<{ text: Partial }> }> grid: Partial<{ line: Partial }> crosshair: Partial<{ line: Partial }> legends: Partial<{ hidden: Partial<{ symbol: CompleteTheme['legends']['hidden']['symbol'] text: CompleteTheme['legends']['hidden']['text'] }> title: Partial<{ text: Partial }> text: Partial ticks: Partial<{ line: Partial text: Partial }> }> labels: Partial<{ text: Partial }> markers: Partial dots: Partial<{ text: Partial }> tooltip: Partial annotations: Partial<{ text: Partial link: Partial outline: Partial symbol: Partial }> }> export function useTheme(): CompleteTheme export function usePartialTheme(theme?: Theme): CompleteTheme export type MotionProps = Partial<{ animate: boolean motionConfig: string | SpringConfig }> export function useMotionConfig(): { animate: boolean config: SpringConfig } export type SvgFillMatcher = (datum: T) => boolean export interface SvgDefsAndFill { defs?: { id: string [key: string]: any }[] fill?: { id: string; match: Record | SvgFillMatcher | '*' }[] } export type CssMixBlendMode = | 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity' export type StackOrder = 'ascending' | 'descending' | 'insideOut' | 'none' | 'reverse' export type StackOffset = 'expand' | 'diverging' | 'none' | 'silhouette' | 'wiggle' export type AreaCurve = | 'basis' | 'cardinal' | 'catmullRom' | 'linear' | 'monotoneX' | 'monotoneY' | 'natural' | 'step' | 'stepAfter' | 'stepBefore' export function useAnimatedPath(path: string): Interpolation // ------------------------------------------------------------------------ // Patterns & Gradients // ------------------------------------------------------------------------ export type GradientColor = { offset: number color: string opacity?: number } export function linearGradientDef( id: string, colors: GradientColor[], options?: React.SVGProps ): { id: string type: 'linearGradient' colors: GradientColor[] } & React.SVGProps export type LinearGradientDef = { id: string type: 'linearGradient' colors: { offset: number color: string opacity?: number }[] gradientTransform?: string } export type PatternDotsDef = { id: string type: 'patternDots' color?: string background?: string size?: number padding?: number stagger?: boolean } export function patternDotsDef( id: string, options?: Omit ): PatternDotsDef export function PatternDots(props: Omit): JSX.Element export type PatternSquaresDef = Omit & { type: 'patternSquares' } export function patternSquaresDef( id: string, options?: Omit ): PatternSquaresDef export function PatternSquares(props: Omit): JSX.Element export type PatternLinesDef = { id: string type: 'patternLines' spacing?: number rotation?: number background?: string color?: string lineWidth?: number } export function patternLinesDef( id: string, options?: Omit ): PatternLinesDef export function PatternLines(props: Omit): JSX.Element export type Def = LinearGradientDef | PatternDotsDef | PatternSquaresDef | PatternLinesDef export type DefsProps = { defs: Def[] } export function Defs(props: DefsProps): JSX.Element // ------------------------------------------------------------------------ // Motion // ------------------------------------------------------------------------ export const defaultAnimate = true type MotionDefaultProps = { animate: true config: 'default' } export const motionDefaultProps: MotionDefaultProps type DefaultMargin = { top: 0 right: 0 bottom: 0 left: 0 } export const defaultMargin: DefaultMargin export function degreesToRadians(degrees: number): number export function radiansToDegrees(radians: number): number export function absoluteAngleDegrees(degrees: number): number export function normalizeAngle(degrees: number): number export function clampArc(startAngle: number, endAngle: number, length?: number): [number, number] type Accessor = T extends string ? U[T] : never export type DatumPropertyAccessor = (datum: RawDatum) => T export function useDimensions( width: number, height: number, margin?: Box ): { margin: Margin innerWidth: number innerHeight: number outerWidth: number outerHeight: number } export function useMeasure(): [ React.RefObject, { left: number; top: number; width: number; height: number } ] type SvgWrapperType = ( props: React.PropsWithChildren<{ width: number height: number margin: Margin defs?: any role?: string ariaLabel?: React.AriaAttributes['aria-label'] ariaLabelledBy?: React.AriaAttributes['aria-labelledby'] ariaDescribedBy?: React.AriaAttributes['aria-describedby'] isFocusable?: boolean }> ) => JSX.Element export const SvgWrapper: SvgWrapperType interface ContainerProps { theme?: Theme renderWrapper?: boolean isInteractive?: boolean animate?: boolean motionConfig?: string | SpringConfig } type ContainerType = (props: React.PropsWithChildren) => JSX.Element export const Container: ContainerType type ResponsiveWrapperType = (props: { children: (dimensions: { width: number; height: number }) => JSX.Element }) => JSX.Element export const ResponsiveWrapper: ResponsiveWrapperType interface ThemeProviderProps { theme?: Theme } type ThemeProviderType = (props: React.PropsWithChildren) => JSX.Element export const ThemeProvider: ThemeProviderType export function getDistance(x1: number, y1: number, x2: number, y2: number): number export function getAngle(x1: number, y1: number, x2: number, y2: number): number export function positionFromAngle( angle: number, distance: number ): { x: number y: number } export type ValueFormat = | string // d3 formatter // explicit formatting function | (Context extends void ? (value: Value) => string : (value: Value, context: Context) => string) export function getValueFormatter( format?: ValueFormat ): Context extends void ? (value: Value) => string : (value: Value, context: Context) => string export function useValueFormatter( format?: ValueFormat ): Context extends void ? (value: Value) => string : (value: Value, context: Context) => string export type PropertyAccessor = // path to use with `lodash.get()` | string // explicit accessor function | ((datum: Datum) => Value) export function getPropertyAccessor( accessor: PropertyAccessor ): (datum: Datum) => Value export function usePropertyAccessor( accessor: PropertyAccessor ): (datum: Datum) => Value export function getRelativeCursor( element: Element, event: React.MouseEvent | React.TouchEvent ): [number, number] export function isCursorInRect( x: number, y: number, width: number, height: number, cursorX: number, cursorY: number ): boolean export interface CartesianMarkerProps { axis: 'x' | 'y' value: V legend?: string legendOrientation?: 'horizontal' | 'vertical' legendPosition?: BoxAlign lineStyle?: Partial textStyle?: Partial } interface CartesianMarkersProps< X extends DatumValue = DatumValue, Y extends DatumValue = DatumValue > { width: number height: number xScale: (value: X) => number yScale: (value: Y) => number markers: CartesianMarkerProps[] } type CartesianMarkersType = ( props: CartesianMarkersProps ) => JSX.Element export const CartesianMarkers: CartesianMarkersType export type CurveFactoryId = | 'basis' | 'basisClosed' | 'basisOpen' | 'bundle' | 'cardinal' | 'cardinalClosed' | 'cardinalOpen' | 'catmullRom' | 'catmullRomClosed' | 'catmullRomOpen' | 'linear' | 'linearClosed' | 'monotoneX' | 'monotoneY' | 'natural' | 'step' | 'stepAfter' | 'stepBefore' // Curve factories compatible d3 line shape generator export type LineCurveFactoryId = | 'basis' | 'cardinal' | 'catmullRom' | 'linear' | 'monotoneX' | 'monotoneY' | 'natural' | 'step' | 'stepAfter' | 'stepBefore' // Curve factories compatible d3 area shape generator export type AreaCurveFactoryId = | 'basis' | 'cardinal' | 'catmullRom' | 'linear' | 'monotoneX' | 'monotoneY' | 'natural' | 'step' | 'stepAfter' | 'stepBefore' export type ClosedCurveFactoryId = | 'basisClosed' | 'cardinalClosed' | 'catmullRomClosed' | 'linearClosed' export const closedCurvePropKeys: ClosedCurveFactoryId[] export const curveFromProp: (interpolation: CurveFactoryId) => CurveFactory export const useCurveInterpolation: (interpolation: CurveFactoryId) => CurveFactory export interface DotsItemSymbolProps { size: number color: string borderWidth: number borderColor: string } export type DotsItemSymbolComponent = React.FunctionComponent export interface DotsItemProps { datum: D x: number y: number size: number color: string borderWidth: number borderColor: string label?: string | number labelTextAnchor?: 'start' | 'middle' | 'end' labelYOffset?: number symbol?: DotsItemSymbolComponent } export const DotsItem: React.FunctionComponent export type ExtractProps = TComponent extends ComponentType ? TProps : never