tfl-ts
Version:
🚇 Fully-typed TypeScript client for Transport for London (TfL) API • Zero dependencies • Auto-generated types • Real-time arrivals • Journey planning • Universal compatibility
245 lines (244 loc) • 8.09 kB
TypeScript
/**
* UI Utilities for TfL API Wrapper
*
* This module provides utilities for building user interfaces with TfL data,
* including line colors, severity helpers, accessibility utilities, and more.
*
* @example
* import { getLineColor, getSeverityCategory, getAccessibleSeverityLabel } from 'tfl-ts/utils/ui';
*
* // Get line colors for styling
* const colors = getLineColor('central'); // { hex: '#E32017', text: 'text-[#E32017]', bg: 'bg-[#E32017]' }
*
* // Get severity category for conditional styling
* const category = getSeverityCategory(6); // 'severe'
*
* // Get accessible label for screen readers
* const label = getAccessibleSeverityLabel(10, 'Good Service'); // 'Good Service - No issues reported'
*/
import { Lines } from '../generated/meta/Line';
import { Severity } from '../generated/meta/Meta';
export type LineId = typeof Lines[number]['id'];
export type SeverityLevel = number;
export type SeverityDescription = typeof Severity[number]['description'];
/**
* Line color information with accessibility considerations
*/
export interface LineColorInfo {
/** Hex color code */
hex: string;
/** Tailwind text color class */
text: string;
/** Tailwind background color class */
bg: string;
/** Whether this color has poor contrast on dark backgrounds */
poorDarkContrast: boolean;
/** Suggested text color for dark backgrounds */
darkText?: string;
/** Suggested background color for dark backgrounds */
darkBg?: string;
}
/**
* Severity category for UI styling
*/
export type SeverityCategory = 'critical' | 'severe' | 'minor' | 'special' | 'good';
/**
* Severity mapping configuration
*/
export interface SeverityMapping {
critical: SeverityLevel[];
severe: SeverityLevel[];
minor: SeverityLevel[];
special: SeverityLevel[];
good: SeverityLevel[];
}
/**
* Official TfL line colors with accessibility considerations
*
* Colors are based on TfL's official brand guidelines and include
* accessibility considerations for dark mode and contrast ratios.
*/
export declare const LINE_COLORS: Record<string, LineColorInfo>;
/**
* Default color for unknown lines
*/
export declare const DEFAULT_LINE_COLOR: LineColorInfo;
/**
* Line ordering by passenger volume and importance
* Used for consistent sorting in UI displays
*/
export declare const LINE_ORDER: readonly string[];
/**
* Build severity mapping from generated TfL data
*
* This creates a smart categorization of severity levels based on
* the actual descriptions from the TfL API, making it easier to
* apply consistent styling across different transport modes.
*/
export declare const buildSeverityMapping: () => SeverityMapping;
/**
* Pre-built severity mapping for immediate use
*/
export declare const SEVERITY_MAPPING: SeverityMapping;
/**
* Get line color information
*
* @param lineId - The line ID to get colors for
* @returns LineColorInfo object with hex, Tailwind classes, and accessibility info
*
* @example
* const colors = getLineColor('central');
* // Returns: { hex: '#E32017', text: 'text-[#E32017]', bg: 'bg-[#E32017]', poorDarkContrast: false }
*/
export declare const getLineColor: (lineId: string) => LineColorInfo;
/**
* Get severity category for a severity level
*
* @param severityLevel - The severity level number
* @returns SeverityCategory for conditional styling
*
* @example
* const category = getSeverityCategory(6); // 'severe'
* const category = getSeverityCategory(10); // 'good'
*/
export declare const getSeverityCategory: (severityLevel: SeverityLevel) => SeverityCategory;
/**
* Get Tailwind CSS classes for severity styling
*
* @param severityLevel - The severity level number
* @param includeAnimation - Whether to include animation classes
* @returns Object with text and animation classes
*
* @example
* const classes = getSeverityClasses(6, true);
* // Returns: { text: 'text-orange-700', animation: 'animate-[pulse_1.5s_ease-in-out_infinite]' }
*/
export declare const getSeverityClasses: (severityLevel: SeverityLevel, includeAnimation?: boolean) => {
text: string;
animation: string;
};
/**
* Get accessible severity label for screen readers
*
* @param severityLevel - The severity level number
* @param description - The severity description
* @returns Accessible label with additional context
*
* @example
* const label = getAccessibleSeverityLabel(10, 'Good Service');
* // Returns: 'Good Service - No issues reported'
*/
export declare const getAccessibleSeverityLabel: (severityLevel: SeverityLevel, description: string) => string;
/**
* Get line order index for sorting
*
* @param lineId - The line ID to get order for
* @returns Order index (lower = higher priority)
*
* @example
* const order = getLineOrder('central'); // 0 (highest priority)
* const order = getLineOrder('unknown'); // LINE_ORDER.length (lowest priority)
*/
export declare const getLineOrder: (lineId: string) => number;
/**
* Check if line statuses indicate normal service
*
* @param statuses - Array of line status objects
* @returns True if all statuses indicate good or special service
*
* @example
* const isNormal = isNormalService(line.lineStatuses);
* if (isNormal) {
* // Apply normal service styling
* }
*/
export declare const isNormalService: (statuses: Array<{
statusSeverity?: SeverityLevel;
}>) => boolean;
/**
* Check if line has night closure
*
* @param statuses - Array of line status objects
* @returns True if any status indicates night closure (severity 20)
*
* @example
* const hasNightClosure = hasNightService(line.lineStatuses);
* if (hasNightClosure) {
* // Show night closure indicator
* }
*/
export declare const hasNightService: (statuses: Array<{
statusSeverity?: SeverityLevel;
}>) => boolean;
/**
* Get ARIA label for line status
*
* @param lineName - The line name
* @param statuses - Array of line status objects
* @returns Accessible ARIA label
*
* @example
* const ariaLabel = getLineAriaLabel('Central', line.lineStatuses);
* // Returns: 'Central line: Good Service - No issues reported'
*/
export declare const getLineAriaLabel: (lineName: string, statuses: Array<{
statusSeverity?: SeverityLevel;
statusSeverityDescription?: string;
}>) => string;
/**
* Get CSS custom properties for line colors
*
* @param lineId - The line ID
* @returns CSS custom properties object
*
* @example
* const cssProps = getLineCssProps('central');
* // Returns: { '--line-color': '#E32017', '--line-color-rgb': '227, 32, 23' }
*/
export declare const getLineCssProps: (lineId: string) => Record<string, string>;
/**
* Sort lines by severity and importance
*
* @param lines - Array of line objects with status information
* @returns Sorted array of lines
*
* @example
* const sortedLines = sortLinesBySeverityAndOrder(lineStatuses);
*/
export declare const sortLinesBySeverityAndOrder: <T extends {
id?: string;
lineStatuses?: Array<{
statusSeverity?: SeverityLevel;
}>;
}>(lines: T[]) => T[];
/**
* Get line display name with mode indicator
*
* @param lineName - The line name
* @param modeName - The transport mode
* @returns Formatted display name
*
* @example
* const displayName = getLineDisplayName('Central', 'tube'); // 'Central'
* const displayName = getLineDisplayName('Liberty', 'overground'); // 'Liberty (Overground)'
*/
export declare const getLineDisplayName: (lineName: string, modeName: string) => string;
/**
* Get line status summary for quick overview
*
* @param statuses - Array of line status objects
* @returns Summary object with worst severity and count
*
* @example
* const summary = getLineStatusSummary(line.lineStatuses);
* // Returns: { worstSeverity: 6, worstDescription: 'Severe Delays', hasIssues: true, issueCount: 1 }
*/
export declare const getLineStatusSummary: (statuses: Array<{
statusSeverity?: SeverityLevel;
statusSeverityDescription?: string;
}>) => {
worstSeverity: number;
worstDescription: string;
hasIssues: boolean;
issueCount: number;
};