UNPKG

react-fa-picker

Version:

A reusable React Icon Picker component, bundled with its own Tailwind CSS build.

111 lines (101 loc) 2.87 kB
/* eslint-disable @typescript-eslint/no-explicit-any */ import { IconDefinition } from "@fortawesome/fontawesome-svg-core"; import * as brands from "@fortawesome/free-brands-svg-icons"; import * as regular from "@fortawesome/free-regular-svg-icons"; import * as solid from "@fortawesome/free-solid-svg-icons"; import { IconCategory, IconType } from "./types"; // Track seen unicodes to filter duplicates globally const seenUnicodes = new Set<string>(); /** * Gets the icon class name */ export const getIconClassName = (iconDef: IconDefinition): string => { if (!iconDef || !iconDef.iconName) return ""; return `fa-${iconDef.iconName}`; }; /** * Gets the icon unicode */ export const getIconUnicode = (icon: IconDefinition): string => { if (!icon || !icon.icon) return ""; const unicodeHex = Array.isArray(icon.icon) && icon.icon.length > 0 ? (icon.icon[3] as string) : ""; return unicodeHex ? `\\u${unicodeHex}` : ""; }; /** * Extract icons from a FontAwesome package */ function extractIcons( pkg: Record<string, any>, categoryName: string, prefixTag: string, ): IconType[] { return Object.values(pkg) .filter( (def): def is IconDefinition & { iconName: string; prefix: string } => Boolean(def?.iconName), ) .map((def) => { const name = def.iconName; const unicode = getIconUnicode(def); return { id: unicode || `${prefixTag}-${name}`, // fallback to name if unicode missing name: `${prefixTag}-${name}`, icon: def, unicode, class: getIconClassName(def), category: categoryName, }; }) .filter((icon) => { if (!icon.unicode || seenUnicodes.has(icon.unicode)) return false; seenUnicodes.add(icon.unicode); return true; }); } /** * Categorized icon list with prefix-tagged names */ const iconCategories: IconCategory[] = [ { name: "Solid", icons: extractIcons(solid, "Solid", "solid") }, { name: "Regular", icons: extractIcons(regular, "Regular", "regular") }, { name: "Brands", icons: extractIcons(brands, "Brands", "brands") }, ]; /** * Get all icons as flat list */ export function getAllIcons(): IconType[] { return iconCategories.flatMap((category) => category.icons); } /** * Get icon categories */ export function getIconCategories(): IconCategory[] { return iconCategories; } /** * Generate random icon name */ export const generateRandomIconName = (prefix = "icon"): string => { const randomId = Math.floor(Math.random() * 10000); const suffixes = [ "home", "user", "settings", "file", "folder", "chart", "mail", "calendar", "map", "image", "video", "audio", "lock", "key", ]; const randomSuffix = suffixes[Math.floor(Math.random() * suffixes.length)]; return `${prefix}-${randomSuffix}-${randomId}`; };