From d5583364e0c6c0f35c2d140e651a12cddc01d67c Mon Sep 17 00:00:00 2001 From: Christopher Kumm Date: Sun, 8 Dec 2024 21:17:59 -0600 Subject: [PATCH] Revert back to original source code --- src/chart.tsx | 19 +++++++++---------- src/typedCharts.tsx | 16 +++++++++------- src/types.ts | 39 +++++++++++++++++++++++++++++++++++++-- src/utils.ts | 19 +++++++++++-------- 4 files changed, 66 insertions(+), 27 deletions(-) diff --git a/src/chart.tsx b/src/chart.tsx index d7c0c2a1..98a1ef30 100644 --- a/src/chart.tsx +++ b/src/chart.tsx @@ -1,8 +1,8 @@ -import { useEffect, useRef, forwardRef, ForwardedRef } from 'react' +import React, { useEffect, useRef, forwardRef } from 'react' import { Chart as ChartJS } from 'chart.js' import type { ChartType, DefaultDataPoint } from 'chart.js' -import type { ChartProps } from './types.js' +import type { ForwardedRef, ChartProps, BaseChartComponent } from './types.js' import { reforwardRef, cloneData, @@ -23,23 +23,22 @@ function ChartComponent< height = 150, width = 300, redraw = false, - datasetIdKey = 'label', + datasetIdKey, type, data, options, plugins = [], - fallbackContent = null, + fallbackContent, updateMode, ...canvasProps - } = props - - const canvasRef = useRef(null) - const chartRef = useRef | null>(null) + } = props as ChartProps + const canvasRef = useRef(null) + const chartRef = useRef() const renderChart = () => { if (!canvasRef.current) return - chartRef.current = new ChartJS(canvasRef.current, { + chartRef.current = new ChartJS(canvasRef.current, { type, data: cloneData(data, datasetIdKey), options: options && { ...options }, @@ -113,4 +112,4 @@ function ChartComponent< ) } -export const Chart = forwardRef(ChartComponent) +export const Chart = forwardRef(ChartComponent) as BaseChartComponent diff --git a/src/typedCharts.tsx b/src/typedCharts.tsx index 3acbf935..a997eaf1 100644 --- a/src/typedCharts.tsx +++ b/src/typedCharts.tsx @@ -1,3 +1,4 @@ +import React, { forwardRef } from 'react' import { Chart as ChartJS, LineController, @@ -11,7 +12,11 @@ import { } from 'chart.js' import type { ChartType, ChartComponentLike } from 'chart.js' -import type { ChartProps } from './types.js' +import type { + ChartProps, + ChartJSOrUndefined, + TypedChartComponent, +} from './types.js' import { Chart } from './chart.js' function createTypedChart( @@ -20,12 +25,9 @@ function createTypedChart( ) { ChartJS.register(registerables) - return (props: ChartProps) => { - // TODO: Configure ESLint to ignore unused variables named `_`. - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { type: _, ...rest } = props - return - } + return forwardRef, Omit, 'type'>>( + (props, ref) => , + ) as TypedChartComponent } export const Line = /* #__PURE__ */ createTypedChart('line', LineController) diff --git a/src/types.ts b/src/types.ts index b173d36a..478ae9a2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,6 @@ -import type { CanvasHTMLAttributes, ReactNode } from 'react' +import type { CanvasHTMLAttributes, MutableRefObject, ReactNode } from 'react' import type { + Chart, ChartType, ChartData, ChartOptions, @@ -8,6 +9,11 @@ import type { UpdateMode, } from 'chart.js' +export type ForwardedRef = + | ((instance: T | null) => void) + | MutableRefObject + | null + export interface ChartProps< TType extends ChartType = ChartType, TData = DefaultDataPoint, @@ -25,6 +31,7 @@ export interface ChartProps< /** * The options object that is passed into the Chart.js chart * @see https://www.chartjs.org/docs/latest/general/options.html + * @default {} */ options?: ChartOptions /** @@ -39,7 +46,7 @@ export interface ChartProps< */ redraw?: boolean /** - * Key name to identify dataset + * Key name to identificate dataset * @default 'label' */ datasetIdKey?: string @@ -56,3 +63,31 @@ export interface ChartProps< */ updateMode?: UpdateMode } + +/** + * @todo Replace `undefined` with `null` + */ +export type ChartJSOrUndefined< + TType extends ChartType = ChartType, + TData = DefaultDataPoint, + TLabel = unknown, +> = Chart | undefined + +export type BaseChartComponent = < + TType extends ChartType = ChartType, + TData = DefaultDataPoint, + TLabel = unknown, +>( + props: ChartProps & { + ref?: ForwardedRef> + }, +) => JSX.Element + +export type TypedChartComponent = < + TData = DefaultDataPoint, + TLabel = unknown, +>( + props: Omit, 'type'> & { + ref?: ForwardedRef> + }, +) => JSX.Element diff --git a/src/utils.ts b/src/utils.ts index a94bd071..164faa0b 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,4 @@ -import type { MouseEvent, ForwardedRef } from 'react' +import type { MouseEvent } from 'react' import type { ChartType, ChartData, @@ -8,6 +8,10 @@ import type { Chart, } from 'chart.js' +import type { ForwardedRef } from './types.js' + +const defaultDatasetIdKey = 'label' + export function reforwardRef(ref: ForwardedRef, value: T) { if (typeof ref === 'function') { ref(value) @@ -46,17 +50,16 @@ export function setDatasets< >( currentData: ChartData, nextDatasets: ChartDataset[], - datasetIdKey: string, + datasetIdKey = defaultDatasetIdKey, ) { const addedDatasets: ChartDataset[] = [] currentData.datasets = nextDatasets.map( - (nextDataset: ChartDataset): ChartDataset => { + (nextDataset: Record) => { // given the new set, find it's current match const currentDataset = currentData.datasets.find( - (dataset: ChartDataset) => - dataset[datasetIdKey as keyof ChartDataset] === - nextDataset[datasetIdKey as keyof ChartDataset], + (dataset: Record) => + dataset[datasetIdKey] === nextDataset[datasetIdKey], ) // There is no original to update, so simply add new one @@ -65,7 +68,7 @@ export function setDatasets< !nextDataset.data || addedDatasets.includes(currentDataset) ) { - return { ...nextDataset } + return { ...nextDataset } as ChartDataset } addedDatasets.push(currentDataset) @@ -81,7 +84,7 @@ export function cloneData< TType extends ChartType = ChartType, TData = DefaultDataPoint, TLabel = unknown, ->(data: ChartData, datasetIdKey: string) { +>(data: ChartData, datasetIdKey = defaultDatasetIdKey) { const nextData: ChartData = { labels: [], datasets: [],