Files
Outpost/Outpost/Support/OutlineIconMapping.swift
T
Puranjay Savar Mattas 2c2f86f79b feat(collections): map Outline's named icon set to SF Symbols
Collection.icon can be a literal emoji or a string key into Outline's
own icon library (~50 custom outline-icons keys + ~90 FontAwesome
keys, per shared/utils/IconLibrary.tsx in outline/outline — a
different mapping than the outline-icons package itself, which is
keyed by PascalCase component name, not the string stored on the
collection). Only emoji was handled before, so most non-emoji
collections fell back to a generic folder glyph.

Covers the high-confidence subset with an unambiguous SF Symbol
match; unmapped keys keep falling back to the folder rather than
risk an invalid symbol name rendering blank.
2026-08-14 01:42:48 +01:00

97 lines
3.5 KiB
Swift

import Foundation
/// Best-effort SF Symbol equivalents for Outline's non-emoji collection icons.
///
/// `Collection.icon` is either a literal emoji or a string key into Outline's
/// own icon set — a mix of custom `outline-icons` components (camelCase keys)
/// and FontAwesome icons (kebab-case keys, e.g. `faCake` → `"cake"`). The
/// canonical key list lives in `outline/outline`'s `shared/utils/IconLibrary.tsx`,
/// not in the `outline-icons` package itself (that's just the raw component
/// library, keyed by PascalCase component name — a different naming scheme).
///
/// SF Symbols has no exact match for everything in that set, so this only
/// covers keys with a confident, unambiguous equivalent. Anything else falls
/// back to the generic folder glyph — better than a blank/invalid symbol name
/// from a wrong guess.
enum OutlineIconMapping {
static func sfSymbolName(for outlineIconKey: String) -> String? {
mapping[outlineIconKey]
}
private static let mapping: [String: String] = [
// Outline's own custom icon set (camelCase keys).
"academicCap": "graduationcap.fill",
"bicycle": "bicycle",
"beaker": "testtube.2",
"buildingBlocks": "cube.fill",
"bookmark": "bookmark.fill",
"browser": "globe",
"collection": "square.grid.2x2.fill",
"coins": "dollarsign.circle.fill",
"camera": "camera.fill",
"carrot": "leaf.fill",
"clock": "clock.fill",
"cloud": "cloud.fill",
"code": "chevron.left.forwardslash.chevron.right",
"database": "cylinder.fill",
"done": "checkmark.circle.fill",
"email": "envelope.fill",
"eye": "eye.fill",
"feedback": "bubble.left.and.bubble.right.fill",
"flame": "flame.fill",
"graph": "chart.line.uptrend.xyaxis",
"globe": "globe",
"hashtag": "number",
"info": "info.circle.fill",
"image": "photo.fill",
"internet": "network",
"leaf": "leaf.fill",
"library": "books.vertical.fill",
"lightbulb": "lightbulb.fill",
"lightning": "bolt.fill",
"letter": "envelope.fill",
"math": "function",
"moon": "moon.fill",
"notepad": "note.text",
"padlock": "lock.fill",
"palette": "paintpalette.fill",
"pencil": "pencil",
"plane": "airplane",
"promote": "megaphone.fill",
"ramen": "fork.knife",
"question": "questionmark.circle.fill",
"server": "server.rack",
"sun": "sun.max.fill",
"shapes": "square.on.circle",
"sport": "sportscourt.fill",
"smiley": "face.smiling.fill",
"target": "target",
"team": "person.3.fill",
"terminal": "terminal.fill",
"thumbsup": "hand.thumbsup.fill",
"truck": "shippingbox.fill",
"tools": "wrench.and.screwdriver.fill",
"vehicle": "car.fill",
"warning": "exclamationmark.triangle.fill",
// FontAwesome icons (kebab-case keys) — high-confidence subset only.
"book": "book.fill",
"cake": "birthday.cake.fill",
"cat": "cat.fill",
"dog": "dog.fill",
"cube": "cube.fill",
"heart": "heart.fill",
"gift": "gift.fill",
"hammer": "hammer.fill",
"laptop": "laptopcomputer",
"map": "map.fill",
"newspaper": "newspaper.fill",
"paw": "pawprint.fill",
"shield": "shield.fill",
"tree": "tree.fill",
"trophy": "trophy.fill",
"umbrella": "umbrella.fill",
"fish": "fish.fill"
]
}