// Shared text-glyph fallbacks for symbol/icon names. Used when an SVG icon path // isn't rendered — e.g. React Native without react-native-svg, or a text-only // list bullet. Resolution tolerates both the Ant-Design-style PascalCase names // the CMS emits ("CheckOutlined", "CloseCircleOutlined") and short lowercase // tokens ("check", "close"), so a checkmark bullet no longer falls back to a dot. export const SYMBOL_GLYPHS: Record = { check: '✓', checkmark: '✓', tick: '✓', close: '✕', xmark: '✕', multiply: '✕', plus: '+', minus: '−', right: '›', left: '‹', up: '⌃', down: '⌄', dot: '•', bullet: '•', info: 'ℹ', question: '?', play: '▶', pause: '⏸', sound: '🔊', volume: '🔊', muted: '🔇', heart: '♥', star: '★', like: '👍', unlock: '🔓', calendar: '📅', cloud: '☁', fire: '🔥', bell: '🔔', message: '💬', smile: '☺', caret: '▾', }; /** * Resolve a symbol/icon name to a single fallback glyph. Returns '' when nothing * matches so callers can supply their own default (e.g. a bullet dot). * Tries an exact key, then a punctuation-stripped key, then the longest token * that is a substring of the normalized name (so "CheckCircleOutlined" → check). */ export function resolveSymbolGlyph(name?: string): string { if (!name) return ''; const key = name.toLowerCase(); if (SYMBOL_GLYPHS[key]) return SYMBOL_GLYPHS[key]; const normalized = key.replace(/[^a-z0-9]/g, ''); if (SYMBOL_GLYPHS[normalized]) return SYMBOL_GLYPHS[normalized]; let best = ''; let bestLen = 0; for (const token of Object.keys(SYMBOL_GLYPHS)) { if (token.length > bestLen && normalized.includes(token)) { best = SYMBOL_GLYPHS[token]; bestLen = token.length; } } return best; }