@@ -4,8 +4,8 @@ import * as React from "react";
44import * as RechartsPrimitive from "recharts" ;
55import type { LegendPayload } from "recharts/types/component/DefaultLegendContent" ;
66import {
7+ Formatter ,
78 NameType ,
8- Payload ,
99 ValueType ,
1010} from "recharts/types/component/DefaultTooltipContent" ;
1111import type { Props as LegendProps } from "recharts/types/component/Legend" ;
@@ -38,16 +38,10 @@ export type CustomTooltipProps = TooltipContentProps<ValueType, NameType> & {
3838 nameKey ?: string ;
3939 labelKey ?: string ;
4040 labelFormatter ?: (
41- label : TooltipContentProps < number , string > [ "label" ] ,
42- payload : TooltipContentProps < number , string > [ "payload" ] ,
43- ) => React . ReactNode ;
44- formatter ?: (
45- value : number | string ,
46- name : string ,
47- item : Payload < number | string , string > ,
48- index : number ,
49- payload : ReadonlyArray < Payload < number | string , string > > ,
41+ label : TooltipContentProps < ValueType , NameType > [ "label" ] ,
42+ payload : TooltipContentProps < ValueType , NameType > [ "payload" ] ,
5043 ) => React . ReactNode ;
44+ formatter ?: Formatter < ValueType , NameType > ;
5145 labelClassName ?: string ;
5246 color ?: string ;
5347} ;
@@ -215,20 +209,23 @@ function ChartTooltipContent({
215209 { ! nestLabel ? tooltipLabel : null }
216210 < div className = "grid gap-1.5" >
217211 { payload . map ( ( item , index ) => {
218- const key = `${ nameKey || item . name || item . dataKey || "value" } ` ;
212+ const key = `${ nameKey || item . name || dataKeyToString ( item . dataKey ) || "value" } ` ;
219213 const itemConfig = getPayloadConfigFromPayload ( config , item , key ) ;
220214 const indicatorColor = color || item . payload . fill || item . color ;
215+ const itemKey = getTooltipItemKey ( item , index ) ;
221216
222217 return (
223218 < div
224- key = { item . dataKey }
219+ key = { itemKey }
225220 className = { cn (
226221 "[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5" ,
227222 indicator === "dot" && "items-center" ,
228223 ) }
229224 >
230- { formatter && item ?. value !== undefined && item . name ? (
231- formatter ( item . value , item . name , item , index , item . payload )
225+ { formatter &&
226+ item . value !== undefined &&
227+ item . name !== undefined ? (
228+ formatter ( item . value , item . name , item , index , payload )
232229 ) : (
233230 < >
234231 { itemConfig ?. icon ? (
@@ -267,9 +264,9 @@ function ChartTooltipContent({
267264 { itemConfig ?. label || item . name }
268265 </ span >
269266 </ div >
270- { item . value && (
267+ { item . value !== undefined && (
271268 < span className = "text-foreground font-mono font-medium tabular-nums" >
272- { item . value . toLocaleString ( ) }
269+ { formatTooltipValue ( item . value ) }
273270 </ span >
274271 ) }
275272 </ div >
@@ -283,6 +280,27 @@ function ChartTooltipContent({
283280 ) ;
284281}
285282
283+ function dataKeyToString ( dataKey : unknown ) : string | undefined {
284+ return typeof dataKey === "string" || typeof dataKey === "number"
285+ ? String ( dataKey )
286+ : undefined ;
287+ }
288+
289+ function getTooltipItemKey (
290+ item : TooltipContentProps < ValueType , NameType > [ "payload" ] [ number ] ,
291+ index : number ,
292+ ) : React . Key {
293+ return dataKeyToString ( item . dataKey ) ?? item . name ?? index ;
294+ }
295+
296+ function formatTooltipValue ( value : ValueType ) : string {
297+ if ( Array . isArray ( value ) ) {
298+ return value . map ( ( entry ) => entry . toLocaleString ( ) ) . join ( " - " ) ;
299+ }
300+
301+ return value . toLocaleString ( ) ;
302+ }
303+
286304const ChartLegend = RechartsPrimitive . Legend ;
287305
288306function ChartLegendContent ( {
@@ -376,9 +394,9 @@ function getPayloadConfigFromPayload(
376394
377395export {
378396 ChartContainer ,
379- ChartTooltip ,
380- ChartTooltipContent ,
381397 ChartLegend ,
382398 ChartLegendContent ,
383399 ChartStyle ,
400+ ChartTooltip ,
401+ ChartTooltipContent ,
384402} ;
0 commit comments