function LegendComponent()

in packages/charts/src/components/legend/legend.tsx [69:180]


function LegendComponent(props: LegendStateProps & LegendDispatchProps) {
  const {
    items,
    size,
    debug,
    isBrushing,
    chartTheme: { chartMargins, legend },
    chartDimensions,
    containerDimensions,
    config,
  } = props;

  const { onLegendItemOut, onLegendItemOver } = config;
  const { onItemOutAction, onItemOverAction } = props;

  const onLegendItemMouseOver = useCallback(
    (seriesIdentifiers: SeriesIdentifier[], path: LegendPath) => {
      // call the settings listener directly if available
      if (onLegendItemOver) {
        onLegendItemOver(seriesIdentifiers);
      }
      onItemOverAction(path);
    },
    [onItemOverAction, onLegendItemOver],
  );

  const onLegendItemMouseOut = useCallback(() => {
    // call the settings listener directly if available
    if (onLegendItemOut) {
      onLegendItemOut();
    }
    onItemOutAction();
  }, [onLegendItemOut, onItemOutAction]);

  if (items.every(({ isItemHidden }) => isItemHidden)) {
    return null;
  }

  const positionConfig = getLegendPositionConfig(config.legendPosition);
  const containerStyle = getLegendStyle(positionConfig, size, legend.margin);
  const listStyle = getLegendListStyle(positionConfig, chartMargins, legend, items.length);
  const isMostlyRTL = hasMostlyRTLItems(items.map(({ label }) => label));

  const legendClasses = classNames('echLegend', {
    'echLegend--debug': debug,
    'echLegend--inert': isBrushing,
    'echLegend--horizontal': positionConfig.direction === LayoutDirection.Horizontal,
    'echLegend--vertical': positionConfig.direction === LayoutDirection.Vertical,
    'echLegend--left': positionConfig.hAlign === HorizontalAlignment.Left,
    'echLegend--right': positionConfig.hAlign === HorizontalAlignment.Right,
    'echLegend--top': positionConfig.vAlign === VerticalAlignment.Top,
    'echLegend--bottom': positionConfig.vAlign === VerticalAlignment.Bottom,
  });

  const itemProps: Omit<LegendItemProps, 'item'> = {
    positionConfig,
    isMostlyRTL,
    totalItems: items.length,
    hiddenItems: items.filter(({ isSeriesHidden }) => isSeriesHidden).length,
    extraValues: props.extraValues,
    legendValues: config.legendValues,
    onLegendItemMouseOver,
    onLegendItemMouseOut,
    onClick: config.onLegendItemClick,
    clearTemporaryColorsAction: props.clearTemporaryColors,
    setPersistedColorAction: props.setPersistedColor,
    setTemporaryColorAction: props.setTemporaryColor,
    toggleDeselectSeriesAction: props.onToggleDeselectSeriesAction,
    colorPicker: config.legendColorPicker,
    action: config.legendAction,
    labelOptions: legend.labelOptions,
    flatLegend: config.flatLegend ?? DEFAULT_LEGEND_CONFIG.flatLegend,
    legendTitle: config.legendTitle,
  };

  const positionStyle = legendPositionStyle(config, size, chartDimensions, containerDimensions);
  const isTableView = shouldDisplayTable(itemProps.legendValues);

  return (
    <div className={legendClasses} style={positionStyle} dir={isMostlyRTL ? 'rtl' : 'ltr'}>
      {config.customLegend ? (
        <div style={containerStyle}>
          <CustomLegend
            component={config.customLegend}
            items={items.map(({ seriesIdentifiers, childId, path, ...customProps }) => ({
              ...customProps,
              seriesIdentifiers,
              path,
              extraValue: itemProps.extraValues.get(seriesIdentifiers[0]?.key ?? '')?.get(childId ?? ''),
              onItemOutAction,
              onItemOverActon: () => onItemOverAction(path),
              onItemClickAction: (negate: boolean) =>
                itemProps.toggleDeselectSeriesAction({ legendItemIds: seriesIdentifiers, metaKey: negate }),
            }))}
          />
        </div>
      ) : isTableView ? (
        <div style={containerStyle} className="echLegendTable__container">
          <LegendTable items={items} {...itemProps} seriesWidth={size.seriesWidth} />
        </div>
      ) : (
        <div style={containerStyle} className="echLegendListContainer">
          <ul style={listStyle} className="echLegendList">
            {items.map((item, index) => (
              <LegendListItem key={`${index}`} item={item} {...itemProps} />
            ))}
          </ul>
        </div>
      )}
    </div>
  );
}