import { useTheme } from '@emotion/react'; import { useMemo } from 'react'; import { mobileVisualisationPalette } from '@hero-design/colors'; import type { Theme } from '../../../../theme'; import type { SegmentedBarData, SegmentedBarStyleConfig } from '../types'; import { SEGMENTED_BAR_COLORS, type SegmentedBarColorToken, } from '../constants'; /** * Retrieves a color value from a theme source by token. */ const getThemeColorValue = ( source: Record | undefined, token: SegmentedBarColorToken ): string | undefined => { const value = source?.[token]; return typeof value === 'string' ? value : undefined; }; /** * Resolves a SegmentedBar color token to a concrete CSS color string. * Falls back to the raw token string if not found. */ const getColorFromList = ({ theme, token, }: { theme: Theme; token: SegmentedBarColorToken; }): string => { return ( getThemeColorValue(theme.colors, token) ?? getThemeColorValue(mobileVisualisationPalette, token) ?? token ); }; /** * Maps custom series colors by matching labels. */ const mapCustomSeriesColors = ({ dataSeries, customSeries, theme, }: { dataSeries: SegmentedBarData; customSeries: NonNullable; theme: Theme; }): string[] => { const colorByLabel = new Map( customSeries.map(({ label, color }) => [ label, getColorFromList({ theme, token: color, }), ]) ); return dataSeries.map(({ label }) => { const resolvedColor = colorByLabel.get(label); return resolvedColor || ''; }); }; /** * Returns an array of colors (index-aligned to the segmented bar data). * * - if `customSeries` is provided, uses the provided series colors (resolved via theme/palette) * - otherwise returns the default palette-based colors */ export const useSegmentedBarColors = ({ dataSeries, customSeries, }: { dataSeries: SegmentedBarData; customSeries?: SegmentedBarStyleConfig['series']; }): string[] => { const theme = useTheme(); const colors = useMemo(() => { if (customSeries !== undefined) { return mapCustomSeriesColors({ dataSeries, customSeries, theme, }); } // Default colors return Array.from({ length: dataSeries.length }, (_, index) => getColorFromList({ theme, token: SEGMENTED_BAR_COLORS[index % SEGMENTED_BAR_COLORS.length], }) ); }, [customSeries, dataSeries, theme]); return colors; };