/** One coloured zone of the track, filled up to (and excluding) `upTo`. */ export interface BandedGaugeBand { /** * Upper boundary of the band on the scale (exclusive). The final band's * `upTo` is conventionally the scale `max` so it fills to the bar end. */ upTo: number; /** * DS token NAME for the band fill — e.g. `'--info'`, `'--success'`, * `'--warning-readable'`, `'--destructive'`. Resolved by the surface's * `resolve` callback (concrete `rgb()` for the card, `var()` for the * widget). Never a hex/rgb literal in source. */ colorToken: string; } /** * A banded-linear gauge. Every visible string (`valueLabel`, `categoryLabel`, * `rangeLabel`, `ariaLabel`) arrives ALREADY TRANSLATED — this module is * i18n-agnostic; the BMI calculator supplies `t()`-resolved text. */ export interface BandedGaugeModel { /** The true value (printed verbatim even when clamped to a bar end). */ value: number; /** Ascending coloured zones; the last `upTo` should equal `max`. */ bands: BandedGaugeBand[]; /** Low end of the drawn scale (maps to the bar's inline start). */ min: number; /** High end of the drawn scale (maps to the bar's inline end). */ max: number; /** Big number rendered above the marker (e.g. `'24.6'`). */ valueLabel: string; /** Band name shown beside the value (e.g. `'normal'`). Pre-translated. */ categoryLabel?: string; /** Range string for the band (e.g. `'18.5–24.9'`). Pre-translated. */ rangeLabel?: string; /** Full accessible name, e.g. `'BMI 24.6 — normal (18.5–24.9)'`. */ ariaLabel: string; /** Threshold tick values drawn under the bar (e.g. `[18.5, 25, 30]`). */ ticks?: number[]; } /** Drawn BMI scale: 15 (deep underweight) → 40 (deep obesity). */ export declare const BMI_BANDED_MIN = 15; export declare const BMI_BANDED_MAX = 40; /** WHO adult cut-offs drawn as ticks under the bar. */ export declare const BMI_BAND_THRESHOLDS: readonly [18.5, 25, 30]; /** * The four WHO zones as `{ upTo, colorToken }`, plus the scale + ticks, so * both the on-screen widget and the insert card share ONE definition: * * underweight < 18.5 → `--info` * normal 18.5–24.9 → `--success` * overweight 25–29.9 → `--warning-readable` (contrast-safe orange) * obese ≥ 30 → `--destructive` (one obese zone) * * `--warning-readable` is the kit's contrast-safe orange token — it already * resolves correctly per theme (orange-600 in light/non-accessible, `--warning` * elsewhere), so NO `document.documentElement` JS override is needed here. */ export declare function bmiBands(): { bands: BandedGaugeBand[]; min: number; max: number; ticks: number[]; }; /** One filled zone rect in card/widget coordinates. */ export interface BandRect { /** Inline-start x of the zone. */ x: number; /** Zone width. */ w: number; /** Token NAME to fill it with (resolved by the surface). */ colorToken: string; } /** The value marker: its drawn x plus the clamp envelope it lives in. */ export interface MarkerGeometry { /** Drawn x of the marker (clamped into `[clampedStart, clampedEnd]`). */ x: number; /** Inline-start x the marker can reach (bar start). */ clampedStart: number; /** Inline-end x the marker can reach (bar end). */ clampedEnd: number; /** * `'start'` when the true value sits below `min` (marker pinned to the bar * start), `'end'` when it sits above `max`, `null` when it's in range. Drives * the out-of-range caret/chevron. */ overflow: 'start' | 'end' | null; } /** A threshold tick: its x plus the scale value it marks. */ export interface TickGeometry { x: number; value: number; } /** Everything the two builders need, derived once. */ export interface BandedGaugeGeometry { /** Outer SVG width. */ width: number; /** Outer SVG height. */ height: number; /** Inline-start x of the bar. */ barStart: number; /** Inline-end x of the bar. */ barEnd: number; /** Bar top y. */ barY: number; /** Bar thickness. */ barH: number; /** Bar corner radius. */ barRadius: number; /** Coloured zones, left → right. */ bands: BandRect[]; /** The value marker. */ marker: MarkerGeometry; /** Threshold ticks under the bar. */ ticks: TickGeometry[]; /** Baseline y for the value label above the bar. */ valueLabelY: number; /** Baseline y for the tick number labels under the bar. */ tickLabelY: number; /** Pre-translated value label (verbatim from the model). */ valueLabel: string; /** Optional `category (range)` summary shown beside the value. */ summaryLabel: string; /** Full accessible name for `` / `aria-label`. */ ariaLabel: string; } /** Layout knobs for {@link computeBandedGaugeGeometry}. */ export interface BandedGaugeLayoutOptions { /** Outer SVG width. */ width: number; /** Outer SVG height. */ height: number; } export declare const INSET_X = 14; /** * Pure geometry pass — the ONE place value→x mapping, band widths, marker * clamping, and tick positions are computed. Both the SVG-string builder and * the JSX component consume this so the two surfaces never drift. * * The marker x is CLAMPED to `[barStart, barEnd]`, but `valueLabel` always * prints the true value; `marker.overflow` flags an out-of-range value so the * surface can draw a caret at the clamped end. */ export declare function computeBandedGaugeGeometry(model: BandedGaugeModel, { width, height }: BandedGaugeLayoutOptions): BandedGaugeGeometry; /** A token-name → concrete-colour resolver supplied by each surface. */ export type ColorResolver = (colorToken: string) => string; /** Theme colours + font + resolver for {@link buildBandedGaugeSvgString}. */ export interface BandedGaugeSvgOptions { /** * Maps a band token NAME to the colour string painted into the markup. The * card passes a probe-resolved `rgb(...)` resolver so the baked PNG carries * theme-correct colours; never a literal in source. */ resolve: ColorResolver; /** Font family for the text (resolved from the theme, e.g. `--font-sans`). */ font: string; /** Foreground colour for the value label + marker (concrete). */ fg: string; /** Muted colour for the tick numbers + summary (concrete). */ muted: string; /** Track / unfilled-rail colour, also used for tick rules (concrete). */ track: string; } export declare function buildBandedGaugeSvgString(geometry: BandedGaugeGeometry, options: BandedGaugeSvgOptions): string; export declare const DEFAULT_HEIGHT = 64; export interface BandedGaugeProps { /** The gauge model (value, bands, scale, pre-translated labels). */ model: BandedGaugeModel; /** SVG width. Defaults to {@link DEFAULT_WIDTH}. */ width?: number; /** SVG height. Defaults to {@link DEFAULT_HEIGHT}. */ height?: number; /** Extra class names on the root `<svg>`. */ className?: string; } /** * Presentational banded-linear gauge for the on-screen widget. Renders the SAME * geometry as {@link buildBandedGaugeSvgString} but as JSX, filling each band * with `fill="var(<token>)"` so the live theme resolves the colour (and a theme * switch repaints with no re-sample). Visually equivalent to the card string. * * The track + marker are decorative; the accessible name on the root carries * the meaning (`role="img"` + `aria-label`, mirrored in `<title>`). All text in * the model is pre-translated by the caller. * * The measurement axis runs low→high left-to-right regardless of document * direction — SVG coordinates are inherently LTR (a `<rect x>` is unaffected by * `direction`), and `direction="ltr"` is pinned on the root to keep any nested * `<text>` directionality explicit. Logical properties govern the surrounding * layout, never this axis. */ export declare const BandedGauge: import("react").ForwardRefExoticComponent<BandedGaugeProps & import("react").RefAttributes<SVGSVGElement>>; //# sourceMappingURL=banded-gauge.d.ts.map