I'm trying to pass some custom components to the Tooltip
, Legend
, XAxis
, and YAxis
components from the recharts
library.
My issue is when I pass the component like
type Props = {
x: number;
y: number;
payload: { value: string };
isGroupedByHour: boolean;
};
const CustomXAxisTick = ({ x, y, payload, isGroupedByHour }: Props) => {...}
<XAxis dataKey="time" tick={<CustomXAxisTick />} />
I get a type error on the <XAxis .../>
line: Type '{ }' is missing the following properties from type 'Props': x, y, payload
. Same for all the custom components.
I've tried passing the components inline like:
<Legend
align="center"
content={(props) => (
<div className="flex flex-shrink-0 items-center justify-center gap-4">
{props.payload?.map((p) => (
<span
key={p.id}
className={`text-xs flex items-center gap-1 `}
>
<span className="h-2 w-2 bg-current" />
{p.dataKey}
</span>
))}
</div>
)}
/>
It works, but I need to reuse the components, so I want them as separate components.
I've also tried directly using the custom components like this:
const CustomLegend = (
<Legend
align="center"
content={(props) => (
<div className="flex flex-shrink-0 items-center justify-center gap-4">
{props.payload?.map((p) => (
<span
key={p.id}
className={`text-xs text-[${p.color}] flex items-center gap-1 `}
>
<span className="h-2 w-2 bg-current" />
{
GRAPH_LABELS.decisions[
p.dataKey as keyof typeof GRAPH_LABELS.decisions
]
}
</span>
))}
</div>
)}
/>
);
<BarChart
data={new Array(100).fill(0).map((row, idx) => {
return {
time: idx,
pass: Math.random() * 10000,
fail: Math.random() * 10000,
cant_decide: Math.random() * 1000,
};
})}
margin={{
top: 20,
right: 30,
left: 20,
bottom: 5,
}}
>
<CustomLegend />
</BarChart>
But recharts
does not render this component at all.
My question is how do I properly type my custom components so that I don't get any type errors.
At least for the CustomXAxisTick and the CustomYAxisTick, it simply works to adapt your code as follows:
<XAxis dataKey="time" tick={(props)=> <CustomXAxisTick {...props}/>} />
<YAxis tick={(props)=> <CustomYAxisTick {...props} />} />
In the other two cases, this does not work because the types you defined are not compatible with the recharts types.
Property 'active' is optional in type '{ separator?: string | undefined; wrapperClassName?: string | undefined; labelClassName?: string | undefined; formatter?: Formatter<ValueType, NameType> | undefined; ... 24 more ...; useTranslate3d?: boolean | undefined; }' but required in type 'ToolTipProps'.
Type '{ content?: ContentType | undefined; iconSize?: number | undefined; iconType?: IconType | undefined; layout?: LayoutType | undefined; align?: HorizontalAlignmentType | undefined; ... 476 more ...; key?: Key | ... 1 more ... | undefined; }' is not assignable to type 'LegendProps'. Types of property 'payload' are incompatible. Type 'Payload[] | undefined' is not assignable to type '{ id: string; color: string; dataKey: string; }[]'. Type 'undefined' is not assignable to type '{ id: string; color: string; dataKey: string; }[]'.
In those two cases you must adapt your types to conform to the expectations from recharts.
I guess this thus only is half an answer, but I hope it is also half valuable, thus already sharing.