UNPKG

@redocly/theme

Version:

Shared UI components lib

58 lines (51 loc) 1.85 kB
export type ResolvedIcon = | { type: 'link'; value: string } | { type: 'font-awesome'; name: string; style: string } | { type: 'invalid'; reason: string }; const FA_ICON_STYLES = ['solid', 'regular', 'duotone', 'brands'] as string[]; const FA_ICON_NAME_PATTERN = /^[a-z0-9-]+$/i; /** * Resolves an icon value from configuration into a structured object. * * Supports: * - URLs (absolute or relative paths to image files) * - Font Awesome icons in formats: * - "solid camera" (style + name) * - "camera" (name only, default style: 'regular') * * @param icon - The icon string from config. * @returns A structured object describing the icon: * - type: 'url' | 'font-awesome' | 'invalid' * - value: for URLs * - name and style: for Font Awesome icons * - reason: for invalid entries */ export function resolveIcon(icon?: string): ResolvedIcon { if (!icon || typeof icon !== 'string') { return { type: 'invalid', reason: 'Icon must be a non-empty string' }; } const trimmed = icon.trim(); const isLink = trimmed.match(/\.(svg|png|jpg|jpeg|gif|ico|webp)$/) || /^https?:\/\//.test(trimmed); if (isLink) { return { type: 'link', value: trimmed }; } const [first, second] = trimmed.split(/\s+/); if (first) { if (second) { // Format: "style name" (e.g., "solid camera") if (FA_ICON_STYLES.includes(first) && FA_ICON_NAME_PATTERN.test(second)) { return { type: 'font-awesome', style: first, name: second }; } else { return { type: 'invalid', reason: 'Unrecognized icon format' }; } } else if (!FA_ICON_STYLES.includes(first) && FA_ICON_NAME_PATTERN.test(first)) { return { type: 'font-awesome', name: first, style: 'regular', }; } } return { type: 'invalid', reason: 'Unrecognized icon format' }; }