Radial Bar Chart with Click to Focus Legend

import { createContext, useContext, useMemo, useState } from 'react';
import {
  DefaultLegendContentProps,
  Legend,
  LegendPayload,
  RadialBar,
  RadialBarChart,
  RadialBarSectorProps,
  Sector,
  useRechartsTheme,
} from 'recharts';
import { generateMockData, RechartsDevtools } from '@recharts/devtools';

const data = generateMockData(6, 134);
const colors = ['#8884d8', '#83a6ed', '#8dd1e1', '#82ca9d', '#a4de6c', '#d0ed57', '#ffc658'];

type SelectedLabelState = {
  selectedLabel: string | undefined;
  setSelectedLabel: (label: string | undefined) => void;
};

const SelectedLabelContext = createContext<SelectedLabelState>({
  selectedLabel: undefined,
  setSelectedLabel: () => {},
});

const CustomSector = (props: RadialBarSectorProps) => {
  const { selectedLabel, setSelectedLabel } = useContext(SelectedLabelContext);
  const isSelected = props.payload.label === selectedLabel || selectedLabel == null;
  return (
    <Sector
      {...props}
      onClick={() => setSelectedLabel(props.payload.label)}
      fill={colors[props.index % colors.length]}
      opacity={isSelected ? 1 : 0.2}
      style={{
        transition: 'opacity 0.3s ease',
      }}
    />
  );
};

const LegendItem = ({ entry }: { entry: LegendPayload }) => {
  const { selectedLabel, setSelectedLabel } = useContext(SelectedLabelContext);
  // @ts-expect-error label is always present in our case, the typings are just not accurate enough
  const l = entry.payload.label;
  const isSelected = selectedLabel === l || selectedLabel == null;
  const theme = useRechartsTheme();
  return (
    // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-noninteractive-element-interactions
    <li
      onClick={() => setSelectedLabel(l)}
      style={{
        color: theme?.typography?.color,
        opacity: isSelected ? 1 : 0.2,
        transition: 'opacity 0.3s ease',
      }}
    >
      {l}
    </li>
  );
};

const LegendContent = ({ payload }: DefaultLegendContentProps) => {
  return (
    <ul>
      {payload?.map((entry, index) => (
        <LegendItem key={`item-${index}`} entry={entry} />
      ))}
    </ul>
  );
};

export default function RadialBarChartClickToFocusLegendExample() {
  const [selectedRadialBar, setSelectedRadialBar] = useState<string | undefined>(undefined);

  const providerValue = useMemo(
    () => ({
      selectedLabel: selectedRadialBar,
      setSelectedLabel: (newLabel: string | undefined) =>
        setSelectedRadialBar(curr => (curr === newLabel ? undefined : newLabel)),
    }),
    [selectedRadialBar],
  );

  return (
    <SelectedLabelContext.Provider value={providerValue}>
      <RadialBarChart data={data} style={{ width: '100%', maxWidth: '500px', aspectRatio: 2 }} responsive>
        <RadialBar background dataKey="x" name="foo" shape={CustomSector} cornerRadius={10} stroke="none" />
        <Legend iconSize={10} width={120} height={140} position="right" content={LegendContent} />
        <RechartsDevtools />
      </RadialBarChart>
    </SelectedLabelContext.Provider>
  );
}