/** * @zendir/ui - Enterprise Utility Functions * * Shared utilities for null-safety, formatting, and defensive coding. * These utilities ensure components never crash due to undefined data. */ /** * Safely access a value with a fallback for null/undefined * @example withNullSafety(data?.temperature, 0) // Returns 0 if undefined */ export declare function withNullSafety(value: T | null | undefined, fallback: T): T; /** * Safely format a number, returning '--' if undefined * @example safeNumber(data?.value, 2) // "123.45" or "--" */ export declare function safeNumber(value: number | null | undefined, decimals?: number, fallback?: string): string; /** * Check if value is a valid finite number */ export declare function isValidNumber(value: unknown): value is number; export interface FormatNumberOptions { decimals?: number; locale?: string; notation?: "standard" | "scientific" | "engineering" | "compact"; unit?: string; signDisplay?: "auto" | "never" | "always" | "exceptZero"; } /** * Format a number with locale-aware formatting and optional unit * @example formatNumber(1234567, { notation: 'compact' }) // "1.2M" */ export declare function formatNumber(value: number | null | undefined, options?: FormatNumberOptions): string; /** * Format a number with tabular (monospace) digits for alignment * Uses font-feature-settings: 'tnum' 1 */ export declare function formatTabular(value: number | null | undefined, decimals?: number): string; /** * Format temperature with unit conversion * @example formatTemperature(25) // "25.0°C" * @example formatTemperature(25, 'fahrenheit') // "77.0°F" */ export declare function formatTemperature(celsius: number | null | undefined, unit?: "celsius" | "fahrenheit" | "kelvin", decimals?: number): string; /** * Format data rate with automatic unit scaling * @example formatDataRate(1500000) // "1.50 Mbps" */ export declare function formatDataRate(bitsPerSecond: number | null | undefined): string; /** * Format distance with automatic unit scaling * @example formatDistance(1500) // "1.50 km" */ export declare function formatDistance(meters: number | null | undefined): string; /** * Format altitude (always in km for space ops) * @example formatAltitude(418.2) // "418.2 km" */ export declare function formatAltitude(km: number | null | undefined): string; /** * Format velocity * @example formatVelocity(7.66) // "7.66 km/s" */ export declare function formatVelocity(kmPerSec: number | null | undefined): string; /** * Format percentage with bounds checking * @example formatPercentage(0.856) // "85.6%" * @example formatPercentage(85.6, false) // "85.6%" (already percentage) */ export declare function formatPercentage(value: number | null | undefined, isDecimal?: boolean, decimals?: number): string; /** * Format power (watts) with auto-scaling * @example formatPower(1500) // "1.50 kW" */ export declare function formatPower(watts: number | null | undefined): string; /** * Format frequency (Hz) with auto-scaling * @example formatFrequency(2400000000) // "2.40 GHz" */ export declare function formatFrequency(hz: number | null | undefined): string; /** * Format duration in human-readable form * @example formatDuration(3661) // "1h 1m 1s" */ export declare function formatDuration(seconds: number | null | undefined): string; /** * Format countdown timer (supports negative values for past events) * @example formatCountdown(125) // "T-02:05" * @example formatCountdown(-60) // "T+01:00" */ export declare function formatCountdown(seconds: number | null | undefined): string; /** * Format UTC timestamp * @example formatUTC(new Date()) // "2026-01-27 14:30:00Z" */ export declare function formatUTC(date: Date | string | null | undefined): string; /** * Format time only (HH:MM:SS) * @example formatTime(new Date()) // "14:30:00" */ export declare function formatTime(date: Date | string | null | undefined, includeSeconds?: boolean): string; /** * Format latitude/longitude * @example formatCoordinate(32.4, 'lat') // "32.40° N" * @example formatCoordinate(-117.2, 'lon') // "117.20° W" */ export declare function formatCoordinate(value: number | null | undefined, type: "lat" | "lon"): string; /** * Format lat/lon pair * @example formatLatLon(32.4, -117.2) // "32.40° N, 117.20° W" */ export declare function formatLatLon(lat: number | null | undefined, lon: number | null | undefined): string; /** * Format angle in degrees * @example formatDegrees(45.5) // "45.5°" */ export declare function formatDegrees(value: number | null | undefined, decimals?: number): string; /** * Format decibels * @example formatDecibels(3.5) // "3.5 dB" */ export declare function formatDecibels(value: number | null | undefined, decimals?: number): string; /** * Clamp a value between min and max * @example clamp(150, 0, 100) // 100 */ export declare function clamp(value: number, min: number, max: number): number; /** * Linear interpolation * @example lerp(0, 100, 0.5) // 50 */ export declare function lerp(start: number, end: number, t: number): number; /** * Map a value from one range to another * @example mapRange(50, 0, 100, 0, 1) // 0.5 */ export declare function mapRange(value: number, inMin: number, inMax: number, outMin: number, outMax: number): number; export type StatusLevel = "off" | "standby" | "normal" | "caution" | "serious" | "critical"; /** * Astro UX Design System status colors * These match the official Astro status semantics */ export declare const STATUS_COLORS: Record; /** * Get status color from level * @example getStatusColor('normal') // '#56f000' */ export declare function getStatusColor(status: StatusLevel | null | undefined): string; /** * Derive status for battery specifically (low is bad) * @example deriveBatteryStatus(25) // 'caution' */ export declare function deriveBatteryStatus(level: number | undefined | null): StatusLevel; /** * Determine status level from a value and thresholds * @example getStatusFromValue(85, { critical: 20, serious: 40, caution: 60, normal: 80 }) // 'normal' */ export declare function getStatusFromValue(value: number | null | undefined, thresholds: { critical?: number; serious?: number; caution?: number; normal?: number; }, higherIsBetter?: boolean): StatusLevel; /** * Normalize any status string to the 6-level StatusLevel system * * @param status - Any status string from domain/backend * @param defaultStatus - Fallback if status is not recognized (default: 'off') * @returns StatusLevel * * @example * ```typescript * normalizeStatus('degraded') // 'caution' * normalizeStatus('nominal') // 'normal' * normalizeStatus('transmitting') // 'normal' * normalizeStatus('warning') // 'caution' * normalizeStatus('error') // 'critical' * normalizeStatus(undefined) // 'off' * ``` */ export declare function normalizeStatus(status: string | undefined | null, defaultStatus?: StatusLevel): StatusLevel; /** * Check if a string is a valid StatusLevel */ export declare function isStatusLevel(value: string): value is StatusLevel; /** * Get the severity order of a status (higher = more severe) * Useful for sorting or finding worst status */ export declare function getStatusSeverity(status: StatusLevel): number; /** * Get the worst (most severe) status from an array * * @example * ```typescript * getWorstStatus(['normal', 'caution', 'normal']) // 'caution' * getWorstStatus(['normal', 'critical', 'caution']) // 'critical' * ``` */ export declare function getWorstStatus(statuses: StatusLevel[]): StatusLevel; /** * Safely add alpha to any CSS color string. * Handles hex (#RRGGBB → #RRGGBBAA), rgb(), and rgba() formats. * * Avoids the common bug of appending a hex alpha string to an rgba() color, * which produces invalid CSS (e.g. "rgba(15, 20, 35, 0.85)80"). * * @param color - CSS color string (hex, rgb, or rgba) * @param alpha - Alpha value 0–1 * @returns Valid CSS color string with alpha applied * * @example * addAlpha('#1b2d3e', 0.5) // '#1b2d3e80' * addAlpha('rgba(15, 20, 35, 0.85)', 0.5) // 'rgba(15, 20, 35, 0.5)' * addAlpha('rgb(15, 20, 35)', 0.031) // 'rgba(15, 20, 35, 0.031)' */ export declare function addAlpha(color: string, alpha: number): string; /** * Merge class names, filtering out falsy values * @example classNames('base', isActive && 'active', className) // "base active custom" */ export declare function classNames(...classes: (string | boolean | undefined | null)[]): string; /** * Generate CSS for tabular numbers (monospace digits) */ export declare const tabularNumsStyle: React.CSSProperties; /** * CSS transition presets */ export declare const transitions: { readonly fast: "all 150ms ease-out"; readonly normal: "all 250ms ease-out"; readonly slow: "all 400ms ease-out"; readonly spring: "all 300ms cubic-bezier(0.34, 1.56, 0.64, 1)"; }; /** * Focus ring styles for accessibility */ export declare const focusRingStyle: React.CSSProperties; /** * Compute a WCAG AA safe version of an accent color for use as foreground text * on dark backgrounds. If the accent already passes 4.5:1 contrast on typical * dark surfaces (L ≈ 0.01), returns it unchanged. Otherwise lightens toward * white until the minimum contrast is met. * * @example safeAccentText('#8b5cf6') // '#a885f8' — lightened to pass 4.5:1 */ export declare function safeAccentText(accent: string): string; export { CategoryPalette } from './categoryPalette';