import { GamutIconProps } from '@codecademy/gamut-icons'; import { ColorAlias } from '@codecademy/gamut-styles'; import { ComponentProps, HTMLProps } from 'react'; import { ButtonProps } from '../../Button'; import { Text } from '../../Typography/Text'; import { HeadingTags } from '../../Typography/types'; import { CustomSortOption } from '../utils/hooks'; import { PartialBarChartTranslations } from './translations'; type titleType = string | { as?: HeadingTags; title: string; variant?: ComponentProps['variant']; }; type BarChartAriaLabel = { title: titleType; 'aria-labelledby'?: never; hideTitle?: boolean; }; type BarChartAriaLabelledBy = { 'aria-labelledby': string; hideTitle?: true; title?: never; }; type BarChartLabel = BarChartAriaLabel | BarChartAriaLabelledBy; /** Props for components that lay out the scale axis (header labels or grid lines) */ export type ScaleAxisLayoutProps = { maxScaleValue: number; tickCount: number; }; /** Maximum value for the value scale (min is always 0) */ export type MaxScaleValue = ScaleAxisLayoutProps['maxScaleValue']; /** Number of labels/ticks on the scale axis. Must be at least 1. */ export type ScaleTickCount = ScaleAxisLayoutProps['tickCount']; export type BarChartStyles = { /** Color for text labels. Defaults to 'text' */ textColor?: ColorAlias; /** Color for the series one bar (seriesOneValue: overlay in stacked charts, only bar in simple charts). Defaults to 'text' */ seriesOneBarColor?: ColorAlias; /** Color for the series two bar (seriesTwoValue: full bar in stacked charts; unused in simple). Defaults to 'primary' */ seriesTwoBarColor?: ColorAlias; /** Color for the series one label (first total value label when stacked, or displayValue when not stacked). Defaults to 'text-secondary' */ seriesOneLabel?: ColorAlias; /** Color for the series two label (displayValue when stacked). Defaults to 'primary' */ seriesTwoLabel?: ColorAlias; }; type BarPropsBase = { /** Label displayed for this category (e.g. on the y-axis) */ categoryLabel: string; /** The foreground/progress bar value (always shown) */ seriesOneValue: number; /** The background/total bar value (optional - creates stacked effect when provided) */ seriesTwoValue?: number; /** Optional gamut-icon to display next to the label */ icon?: React.ComponentType; }; type BarPropsWithoutInteraction = BarPropsBase & { onClick?: never; href?: never; }; type BarPropsWithInteraction = BarPropsBase & { onClick?: ButtonProps['onClick']; href?: HTMLProps['href']; }; export type BarProps = BarPropsWithoutInteraction | BarPropsWithInteraction; /** * Helper type that extracts the element type from an array of bars. * Handles both mutable and readonly arrays. */ export type InferBarType = T extends readonly (infer U)[] ? U extends BarProps ? U : BarProps : T extends (infer U)[] ? U extends BarProps ? U : BarProps : BarProps; export type BarChartProps = BarChartLabel & { /** Whether to animate bars on mount */ animate?: boolean; /** Array of bar data to render */ barValues: TBarValues; /** Figure caption for the BarChart. This should be a summary of the information or the overall takeaway of the information in the chart */ description: string; /** Hides the visual figcaption */ hideDescription?: boolean; /** Hides the visual title for the chart UL */ hideTitle?: boolean; /** Maximum value for the value scale */ maxScaleValue: MaxScaleValue; /** Unit label to display (e.g., "XP") */ unit?: string; /** Style configuration for colors */ styleConfig?: BarChartStyles; /** Interval for the value scale markers */ scaleInterval?: number; /** Array of sort options to display in the dropdown. Can include string literals ('alphabetically', 'numerically', 'none') or custom sort functions. If not provided, the Select dropdown will not render. */ sortFns?: ('alphabetically' | 'numerically' | 'none' | CustomSortOption>)[]; /** * Translations for internationalization. Partial translations are merged with defaults. * Accessibility is function-only. Two optional keys: stackedBarSummary, singleValueBarSummary. * stackedBarSummary: used for stacked (two-value) rows; context includes gained (seriesTwoValue - seriesOneValue). * singleValueBarSummary: used for all single-value rows; the returned string is set as aria-label on the row's link/button when interactive, or rendered in screenreader-only text when not. */ translations?: PartialBarChartTranslations; }; export type BarChartUnit = Pick; export {};