/** * Inline SVG icon library for the plank training app. * * Each icon is a 24x24 Material-style path. We bake the color directly into * the SVG data URI, so consumers can switch between "active" and "inactive" * variants by simply selecting a different key — no font loading, no CSS * pseudo-element tricks, and exact pixel rendering at any size. * * Usage: * const icons = require('../../utils/icons') * const map = icons.build({ primary: '#FF6B35', primaryLight: '#FF8C5A', success: '#4CAF50' }) * // map.playFill => "data:image/svg+xml;..." (orange play) * // map.play => "data:image/svg+xml;..." (gray play) * * Naming convention: * = outlined / inactive (neutral gray) * Fill = filled / active (theme color) */ const PATHS = { // Navigation & UI home: '', homeFill: '', calendar: '', calendarFill: '', settings: '', settingsFill: '', back: '', right: '', close: '', check: '', // Status & feedback hot: '', hotFill: '', like: '', likeFill: '', // Training specific play: '', playFill: '', stop: '', stopFill: '', pause: '', pauseFill: '', time: '', timeFill: '', // Markers & targets target: '', targetFill: '', mark: '', markFill: '', // Stats & charts rank: '', rankFill: '', crown: '', crownFill: '', // Trophy (record celebrations) — Material emoji-events trophy: '', trophyFill: '', // Badge icons (training milestone medals) — replace the old emoji set. // Single-color fills; a gray (locked) and white White // (unlocked, sits on the theme-color disc) variant are both built. bolt: '', moon: '', diamond: '', star: '', // Party popper (first-time celebrations) — Material celebration party: '', partyFill: '', // Sparkle (generic celebrations + confetti particles) sparkle: '', sparkleFill: '', form: '', formFill: '', // Notification notification: '', notificationFill: '', notificationForbid: '', notificationForbidFill: '', // People & users people: '', peopleFill: '', // Actions delete: '', deleteFill: '', info: '', infoFill: '', // Theme & preferences skin: '', skinFill: '', // Lightbulb & tip light: '', lightFill: '', // Voice voice: '', voiceFill: '', // Round check roundCheck: '', roundCheckFill: '', // Emoji / face emoji: '', emojiFill: '', // Edit (pencil) edit: '', editFill: '' } // NOTE: must encodeURIComponent the SVG so that the `#` in colors like // `#FF6B35` doesn't get parsed as a fragment-identifier delimiter — that // would silently truncate the SVG and the image would fail to render. const _svg = (path, color) => { const svg = '' + path + '' return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg) } const INACTIVE = '#999999' const DANGER = '#E53935' /** * Build an icon map keyed by name. Two variants per name: * = inactive (gray) * Fill = active (theme primary) * Plus semantic aliases (delete, etc.) with appropriate colors. * * @param {object} theme - { primary, primaryLight, success, danger } * @returns {object} { : dataUri, ... } */ const build = (theme) => { const t = theme || {} const p = t.primary || '#FF6B35' const s = t.success || '#4CAF50' const d = t.danger || DANGER const out = {} Object.keys(PATHS).forEach((name) => { if (name.endsWith('Fill')) { // Fill variant: filled path + primary color. // Do NOT write out[base] here — that would overwrite the outlined // variant set by the base-name entry below with the wrong path. out[name] = _svg(PATHS[name], p) } else { // Outlined variant: outlined path + inactive gray. out[name] = _svg(PATHS[name], INACTIVE) } }) // Semantic overrides out.deleteActive = _svg(PATHS.deleteFill, d) out.deleteInactive = _svg(PATHS.delete, INACTIVE) out.successFill = _svg(PATHS.roundCheckFill, s) out.successLine = _svg(PATHS.roundCheck, INACTIVE) // White variants for icons sitting on the theme-gradient card / disc // (completion modal, podium accents, the index hero card, etc.) AND for // icons rendered on the primary (filled) buttons, whose background is the // same theme color as a *Fill variant — orange-on-orange would vanish. // Baked-in white is REQUIRED: these are data-URI SVG tags, so CSS // color / currentColor cannot recolor them; only a white SVG works. out.trophyWhite = _svg(PATHS.trophyFill, '#FFFFFF') out.partyWhite = _svg(PATHS.partyFill, '#FFFFFF') out.hotWhite = _svg(PATHS.hotFill, '#FFFFFF') out.formWhite = _svg(PATHS.formFill, '#FFFFFF') out.playWhite = _svg(PATHS.playFill, '#FFFFFF') out.sparkleWhite = _svg(PATHS.sparkleFill, '#FFFFFF') out.checkWhite = _svg(PATHS.check, '#FFFFFF') // Badge white variants — sit on the theme-color (filled) node disc. out.boltWhite = _svg(PATHS.bolt, '#FFFFFF') out.moonWhite = _svg(PATHS.moon, '#FFFFFF') out.diamondWhite = _svg(PATHS.diamond, '#FFFFFF') out.starWhite = _svg(PATHS.star, '#FFFFFF') out.crownWhite = _svg(PATHS.crown, '#FFFFFF') return out } module.exports = { build, PATHS, INACTIVE }