/** * Shared presentation primitives for the LiteLLM plugin. * * The plugin renders inside whatever Backstage theme the host app supplies, so * everything here derives its colour from the MUI palette rather than hard-coded * values. The one exception is the chart series palette: Recharts has no theme * awareness, and its stock colours (#8884d8 / #82ca9d / #ffc658) read as a demo * rather than a product, so we ship a curated ramp that holds up on both light * and dark surfaces. */ import React from 'react'; import type { SxProps, Theme } from '@mui/material/styles'; /** `2026-08-16` → `Aug 16`. Falls back to the raw value for anything else. */ export declare const fmtDateShort: (value: string) => string; /** 54253484 → `54.3M`. Keeps axis labels from swallowing the plot area. */ export declare const fmtCompact: (n: number) => string; /** Compact currency for axis ticks — `$24`, `$1.2K`. */ export declare const fmtUsdCompact: (n: number) => string; /** Categorical ramp, ordered so neighbouring series stay distinguishable. */ export declare const CHART_COLORS: readonly ["#6366F1", "#14B8A6", "#F59E0B", "#EC4899", "#38BDF8", "#84CC16", "#F97316", "#A855F7"]; /** Fixed colours for series that carry meaning rather than identity. */ export declare const SERIES: { readonly input: "#6366F1"; readonly output: "#14B8A6"; readonly success: "#10B981"; readonly failure: "#EF4444"; readonly spend: "#F59E0B"; readonly budget: "#EF4444"; }; /** Stable colour per series name, so a model keeps its colour across charts. */ export declare function chartColor(name: string): string; /** Axis / grid / legend props shared by every chart, derived from the theme. */ export declare function useChartTheme(): { grid: { stroke: string; strokeDasharray: string; vertical: boolean; }; axis: { tick: { fontSize: number; fill: string; }; tickLine: boolean; axisLine: { stroke: string; }; }; legend: { wrapperStyle: { fontSize: number; color: string; paddingTop: number; }; iconType: "circle"; iconSize: number; }; cursor: { fill: string; }; }; interface ChartTooltipProps { active?: boolean; label?: string | number; payload?: Array<{ name?: string; value?: number; color?: string; dataKey?: string | number; }>; /** Formats each series value; defaults to a localised integer. */ valueFormatter?: (value: number) => string; /** Formats the header; defaults to the short date form. */ labelFormatter?: (label: string) => string; /** Drop zero-valued series — useful for stacked charts with many series. */ hideZero?: boolean; } /** * Recharts' default tooltip is an opaque white card with a hard border — it * disappears on dark themes. This one uses the theme's own surface tokens. */ export declare const ChartTooltip: React.FC; /** * Colour key rendered outside the SVG. Recharts' own `` cannot ellipsize, * so a handful of fully-qualified model names ("bedrock/eu.anthropic.…") wrap * into a ragged block that eats the plot area. */ export declare const SeriesLegend: React.FC<{ series: Array<{ name: string; color: string; }>; }>; export type Tone = 'neutral' | 'success' | 'warning' | 'danger' | 'info' | 'accent'; /** * A soft status badge. Deliberately *not* MUI's filled `Chip` — host themes * tend to render those as saturated pills, and a table with one screaming * orange pill per row is unreadable. Tinted background, hairline border, * squared-off corners. */ export declare const StatusPill: React.FC<{ label: React.ReactNode; tone?: Tone; /** Show the leading tone dot. */ dot?: boolean; title?: string; sx?: SxProps; }>; /** Quiet monospace tag for identifiers: model names, team slugs, roles. */ export declare const TagChip: React.FC<{ label: React.ReactNode; title?: string; mono?: boolean; }>; /** Page-level surface with a consistent title row. */ export declare const SectionCard: React.FC<{ title?: React.ReactNode; subtitle?: React.ReactNode; actions?: React.ReactNode; /** Set when the body renders its own edge-to-edge content (e.g. a table). */ flush?: boolean; children: React.ReactNode; }>; /** Bordered frame around a single chart, with its own caption row. */ export declare const ChartCard: React.FC<{ title: React.ReactNode; meta?: React.ReactNode; height?: number; children: React.ReactNode; }>; export interface MetricDef { label: string; value: string; hint?: string; tone?: Tone; } /** * KPI row rendered as one framed strip divided into cells, rather than four * loose cards. Cells share a baseline grid so the numbers line up even when * only some of them carry a hint. */ export declare const MetricStrip: React.FC<{ metrics: MetricDef[]; }>; /** Label + value pair used inside cards. */ export declare const Stat: React.FC<{ label: string; value: React.ReactNode; }>; /** * Progress meter with an explicitly drawn track. MUI's `LinearProgress` tints * its track from the bar colour, which makes an empty bar look full. */ export declare const Meter: React.FC<{ value: number; tone?: Tone; height?: number; }>; /** * Ring gauge for at-a-glance ratios. Hand-drawn SVG rather than MUI's * `CircularProgress`: the track has to stay a neutral hairline (MUI tints it * from the bar colour, so an empty ring reads as full), and the value may * legitimately exceed 100% — the arc clamps at a full turn while the centre * label keeps the real number. */ export declare const Gauge: React.FC<{ /** Share consumed, 0..100+ (unclamped for the label). */ value: number; tone?: Tone; /** Outer diameter in px. */ size?: number; /** Ring thickness in px. */ thickness?: number; /** Centre content; defaults to the rounded percentage. */ label?: React.ReactNode; /** Small caption under the value, inside the ring. */ caption?: React.ReactNode; }>; /** * Secondary navigation inside a card. Hand-rolled rather than a second set of * `Tabs` so it reads as subordinate to the page tabs instead of competing * with them, and so host theme overrides on `MuiTab` don't leak in. */ export declare function SegmentedControl({ value, onChange, options, }: { value: T; onChange: (value: T) => void; options: Array<{ value: T; label: string; }>; }): React.JSX.Element; /** * Shared table chrome: quiet uppercase headers, hairline row rules, a hover * highlight, and tabular figures so numeric columns align. */ export declare const dataTableSx: SxProps; /** Muted icon button that only picks up its semantic colour on hover. */ export declare const quietIconButtonSx: (tone?: Tone) => SxProps; /** Centered empty / loading state for a card body. */ export declare const EmptyState: React.FC<{ message: string; hint?: string; height?: number; action?: React.ReactNode; }>; export {};