UNPKG

@nivo/core

Version:
504 lines (441 loc) 13.4 kB
import { ComponentType, FocusEvent, JSX, KeyboardEvent, MouseEvent, SyntheticEvent, WheelEvent, Ref, } from 'react' import * as React from 'react' import { Interpolation, SpringConfig } from '@react-spring/web' import { CurveFactory } from 'd3-shape' import { PartialTheme } from '@nivo/theming' 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 Padding = Margin export type Box = Partial<Margin> export type BoxAlign = | 'center' | 'top-left' | 'top' | 'top-right' | 'right' | 'bottom-right' | 'bottom' | 'bottom-left' | 'left' export const boxAlignments: readonly BoxAlign[] export function alignBox(box: AlignBox, container: AlignBox, alignment: BoxAlign): [number, number] export type GetColor<T> = (datum: T) => string export type Colors = readonly string[] | string export interface ColorProps<T> { colors?: Colors colorBy?: string | GetColor<T> } export type MotionProps = Partial<{ animate: boolean motionConfig: string | SpringConfig }> export function useMotionConfig(): { animate: boolean config: SpringConfig } export type SvgFillMatcher<T> = (datum: T) => boolean export interface SvgDefsAndFill<T> { defs?: readonly { id: string [key: string]: any }[] fill?: readonly { id: string; match: Record<string, unknown> | SvgFillMatcher<T> | '*' }[] } 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<string> // ------------------------------------------------------------------------ // Patterns & Gradients // ------------------------------------------------------------------------ export type GradientColor = { offset: number color: string opacity?: number } export function linearGradientDef( id: string, colors: GradientColor[], options?: React.SVGProps<SVGLinearGradientElement> ): { id: string type: 'linearGradient' colors: GradientColor[] } & React.SVGProps<SVGLinearGradientElement> 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, 'id' | 'type'> ): PatternDotsDef export function PatternDots(props: Omit<PatternDotsDef, 'type'>): JSX.Element export type PatternSquaresDef = Omit<PatternDotsDef, 'type'> & { type: 'patternSquares' } export function patternSquaresDef( id: string, options?: Omit<PatternSquaresDef, 'id' | 'type'> ): PatternSquaresDef export function PatternSquares(props: Omit<PatternSquaresDef, 'type'>): 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, 'id' | 'type'> ): PatternLinesDef export function PatternLines(props: Omit<PatternLinesDef, 'type'>): JSX.Element export type Def = LinearGradientDef | PatternDotsDef | PatternSquaresDef | PatternLinesDef export type DefsProps = { defs: readonly 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 midAngle(arc: { startAngle: number; endAngle: number }): number export function positionFromAngle( angle: number, distance: number ): { x: number y: number } export function normalizeAngleDegrees(degrees: number): number export function clampArc(startAngle: number, endAngle: number, length?: number): [number, number] type Accessor<T extends keyof U, U> = T extends string ? U[T] : never export type DatumPropertyAccessor<RawDatum, T> = (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<HTMLDivElement>, { 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 ref?: React.Ref<SVGSVGElement> }> ) => JSX.Element export const SvgWrapper: SvgWrapperType interface ContainerProps { theme?: PartialTheme renderWrapper?: boolean isInteractive?: boolean animate?: boolean motionConfig?: string | SpringConfig } type ContainerType = (props: React.PropsWithChildren<ContainerProps>) => JSX.Element export const Container: ContainerType type ResponsiveWrapperType = (props: { children: (dimensions: { width: number; height: number }) => JSX.Element defaultWidth?: number defaultHeight?: number onResize?: (dimensions: { width: number; height: number }) => void debounceResize?: number }) => JSX.Element export const ResponsiveWrapper: ResponsiveWrapperType export type ResponsiveProps<Props> = Omit<Props, 'width' | 'height'> & { defaultWidth?: number defaultHeight?: number onResize?: (dimensions: { width: number; height: number }) => void debounceResize?: number } 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 type ValueFormat<Value, Context = void> = | string // d3 formatter // explicit formatting function | (Context extends void ? (value: Value) => string : (value: Value, context: Context) => string) export function getValueFormatter<Value, Context = void>( format?: ValueFormat<Value, Context> ): Context extends void ? (value: Value) => string : (value: Value, context: Context) => string export function useValueFormatter<Value, Context = void>( format?: ValueFormat<Value, Context> ): Context extends void ? (value: Value) => string : (value: Value, context: Context) => string export type PropertyAccessor<Datum, Value> = // path to use with `lodash.get()` | string // explicit accessor function | ((datum: Datum) => Value) export function getPropertyAccessor<Datum, Value>( accessor: PropertyAccessor<Datum, Value> ): (datum: Datum) => Value export function usePropertyAccessor<Datum, Value>( accessor: PropertyAccessor<Datum, Value> ): (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<V extends DatumValue = DatumValue> { axis: 'x' | 'y' value: V legend?: string legendOrientation?: 'horizontal' | 'vertical' legendPosition?: BoxAlign lineStyle?: Partial<React.CSSProperties> textStyle?: Partial<React.CSSProperties> } interface CartesianMarkersProps< X extends DatumValue = DatumValue, Y extends DatumValue = DatumValue, > { width: number height: number xScale: (value: X) => number yScale: (value: Y) => number markers: readonly CartesianMarkerProps<X | Y>[] } type CartesianMarkersType = <X extends DatumValue = DatumValue, Y extends DatumValue = DatumValue>( props: CartesianMarkersProps<X, Y> ) => 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: readonly ClosedCurveFactoryId[] export const curveFromProp: (interpolation: CurveFactoryId) => CurveFactory export const useCurveInterpolation: (interpolation: CurveFactoryId) => CurveFactory export interface DotsItemSymbolProps<D = any> { datum: D size: number color: string borderWidth: number borderColor: string } export type DotsItemSymbolComponent<D = any> = React.FunctionComponent<DotsItemSymbolProps<D>> export interface DotsItemProps<D = any> { 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<D> ariaLabel?: React.AriaAttributes['aria-label'] ariaLabelledBy?: React.AriaAttributes['aria-labelledby'] ariaDescribedBy?: React.AriaAttributes['aria-describedby'] ariaHidden?: React.AriaAttributes['aria-hidden'] ariaDisabled?: React.AriaAttributes['aria-disabled'] isFocusable?: boolean tabIndex?: number onFocus?: (datum: D, event: React.FocusEvent<SVGGElement>) => void onBlur?: (datum: D, event: React.FocusEvent<SVGGElement>) => void testId?: string } export const DotsItem: React.FunctionComponent<DotsItemProps> export type ExtractProps<TComponent> = TComponent extends ComponentType<infer TProps> ? TProps : never export const mergeRefs: <T>(...refs: (React.Ref<T> | undefined)[]) => (value: T) => void export type BoxAnchor = | 'center' | 'top-left' | 'top' | 'top-right' | 'right' | 'bottom-right' | 'bottom' | 'bottom-left' | 'left' export const BOX_ANCHORS: readonly BoxAnchor[] export type DefaultChartContext = Record<string, unknown> export const ChartContext: React.Context<DefaultChartContext> export type EventMap = { onMouseEnter: MouseEvent onMouseMove: MouseEvent onMouseLeave: MouseEvent onClick: MouseEvent onDoubleClick: MouseEvent onFocus: FocusEvent onBlur: FocusEvent onKeyDown: KeyboardEvent onWheel: WheelEvent onContextMenu: MouseEvent } export type NodeEventHandler<NodeType, E extends SyntheticEvent> = ( node: NodeType, event: E ) => void export type InteractionHandlers<Node, EM extends Record<string, SyntheticEvent>> = { [K in keyof EM]?: NodeEventHandler<Node, EM[K]> } export type SvgElementTag = Exclude< { [K in keyof JSX.IntrinsicElements]: JSX.IntrinsicElements[K] extends React.SVGProps<SVGElement> ? K : never }[keyof JSX.IntrinsicElements], 'svg' > type HtmlElementTag = { [K in keyof JSX.IntrinsicElements]: JSX.IntrinsicElements[K] extends React.HTMLAttributes<HTMLElement> ? K : never }[keyof JSX.IntrinsicElements] export type WithChartRef< Props, T extends SVGSVGElement | HTMLCanvasElement | HTMLDivElement, > = Props & { ref?: Ref<T> }