shared/utils/IconLibrary.tsx
Rama main · réplica de lectura del repositorio original.
// Import icons individually — the package barrel is also loaded as a whole pack
// by the Mermaid extension, so a shared import puts every icon in the bundle.
import { faAndroid } from "@fortawesome/free-brands-svg-icons/faAndroid";
import { faApple } from "@fortawesome/free-brands-svg-icons/faApple";
import { faBluesky } from "@fortawesome/free-brands-svg-icons/faBluesky";
import { faCodepen } from "@fortawesome/free-brands-svg-icons/faCodepen";
import { faDiscord } from "@fortawesome/free-brands-svg-icons/faDiscord";
import { faDocker } from "@fortawesome/free-brands-svg-icons/faDocker";
import { faDropbox } from "@fortawesome/free-brands-svg-icons/faDropbox";
import { faGithub } from "@fortawesome/free-brands-svg-icons/faGithub";
import { faGitlab } from "@fortawesome/free-brands-svg-icons/faGitlab";
import { faPaypal } from "@fortawesome/free-brands-svg-icons/faPaypal";
import { faPython } from "@fortawesome/free-brands-svg-icons/faPython";
import { faShopify } from "@fortawesome/free-brands-svg-icons/faShopify";
import { faSlack } from "@fortawesome/free-brands-svg-icons/faSlack";
import { faSquareJs } from "@fortawesome/free-brands-svg-icons/faSquareJs";
import { faSwift } from "@fortawesome/free-brands-svg-icons/faSwift";
import { faWebAwesome } from "@fortawesome/free-brands-svg-icons/faWebAwesome";
import { faWindows } from "@fortawesome/free-brands-svg-icons/faWindows";
import { faXTwitter } from "@fortawesome/free-brands-svg-icons/faXTwitter";
import { faBagShopping } from "@fortawesome/free-solid-svg-icons/faBagShopping";
import { faBook } from "@fortawesome/free-solid-svg-icons/faBook";
import { faBrush } from "@fortawesome/free-solid-svg-icons/faBrush";
import { faCake } from "@fortawesome/free-solid-svg-icons/faCake";
import { faCat } from "@fortawesome/free-solid-svg-icons/faCat";
import { faCircle } from "@fortawesome/free-solid-svg-icons/faCircle";
import { faClapperboard } from "@fortawesome/free-solid-svg-icons/faClapperboard";
import { faCompactDisc } from "@fortawesome/free-solid-svg-icons/faCompactDisc";
import { faCookieBite } from "@fortawesome/free-solid-svg-icons/faCookieBite";
import { faCrow } from "@fortawesome/free-solid-svg-icons/faCrow";
import { faCrown } from "@fortawesome/free-solid-svg-icons/faCrown";
import { faCube } from "@fortawesome/free-solid-svg-icons/faCube";
import { faDiamond } from "@fortawesome/free-solid-svg-icons/faDiamond";
import { faDisplay } from "@fortawesome/free-solid-svg-icons/faDisplay";
import { faDna } from "@fortawesome/free-solid-svg-icons/faDna";
import { faDog } from "@fortawesome/free-solid-svg-icons/faDog";
import { faDollarSign } from "@fortawesome/free-solid-svg-icons/faDollarSign";
import { faDroplet } from "@fortawesome/free-solid-svg-icons/faDroplet";
import { faFaceDizzy } from "@fortawesome/free-solid-svg-icons/faFaceDizzy";
import { faFaceGrinStars } from "@fortawesome/free-solid-svg-icons/faFaceGrinStars";
import { faFaceLaugh } from "@fortawesome/free-solid-svg-icons/faFaceLaugh";
import { faFaceMeh } from "@fortawesome/free-solid-svg-icons/faFaceMeh";
import { faFaceSmileBeam } from "@fortawesome/free-solid-svg-icons/faFaceSmileBeam";
import { faFaceSmileWink } from "@fortawesome/free-solid-svg-icons/faFaceSmileWink";
import { faFaceSurprise } from "@fortawesome/free-solid-svg-icons/faFaceSurprise";
import { faFeather } from "@fortawesome/free-solid-svg-icons/faFeather";
import { faFish } from "@fortawesome/free-solid-svg-icons/faFish";
import { faFlaskVial } from "@fortawesome/free-solid-svg-icons/faFlaskVial";
import { faFolderClosed } from "@fortawesome/free-solid-svg-icons/faFolderClosed";
import { faGamepad } from "@fortawesome/free-solid-svg-icons/faGamepad";
import { faGauge } from "@fortawesome/free-solid-svg-icons/faGauge";
import { faGem } from "@fortawesome/free-solid-svg-icons/faGem";
import { faGift } from "@fortawesome/free-solid-svg-icons/faGift";
import { faHammer } from "@fortawesome/free-solid-svg-icons/faHammer";
import { faHandsClapping } from "@fortawesome/free-solid-svg-icons/faHandsClapping";
import { faHeart } from "@fortawesome/free-solid-svg-icons/faHeart";
import { faHexagon } from "@fortawesome/free-solid-svg-icons/faHexagon";
import { faIndustry } from "@fortawesome/free-solid-svg-icons/faIndustry";
import { faKitMedical } from "@fortawesome/free-solid-svg-icons/faKitMedical";
import { faLaptop } from "@fortawesome/free-solid-svg-icons/faLaptop";
import { faLaptopCode } from "@fortawesome/free-solid-svg-icons/faLaptopCode";
import { faMagnet } from "@fortawesome/free-solid-svg-icons/faMagnet";
import { faMap } from "@fortawesome/free-solid-svg-icons/faMap";
import { faMicrochip } from "@fortawesome/free-solid-svg-icons/faMicrochip";
import { faMountainSun } from "@fortawesome/free-solid-svg-icons/faMountainSun";
import { faMugHot } from "@fortawesome/free-solid-svg-icons/faMugHot";
import { faNetworkWired } from "@fortawesome/free-solid-svg-icons/faNetworkWired";
import { faNewspaper } from "@fortawesome/free-solid-svg-icons/faNewspaper";
import { faPaintRoller } from "@fortawesome/free-solid-svg-icons/faPaintRoller";
import { faPassport } from "@fortawesome/free-solid-svg-icons/faPassport";
import { faPaw } from "@fortawesome/free-solid-svg-icons/faPaw";
import { faPenRuler } from "@fortawesome/free-solid-svg-icons/faPenRuler";
import { faPentagon } from "@fortawesome/free-solid-svg-icons/faPentagon";
import { faPesoSign } from "@fortawesome/free-solid-svg-icons/faPesoSign";
import { faPhoneVolume } from "@fortawesome/free-solid-svg-icons/faPhoneVolume";
import { faPizzaSlice } from "@fortawesome/free-solid-svg-icons/faPizzaSlice";
import { faPrescription } from "@fortawesome/free-solid-svg-icons/faPrescription";
import { faPuzzlePiece } from "@fortawesome/free-solid-svg-icons/faPuzzlePiece";
import { faRainbow } from "@fortawesome/free-solid-svg-icons/faRainbow";
import { faRecordVinyl } from "@fortawesome/free-solid-svg-icons/faRecordVinyl";
import { faRoad } from "@fortawesome/free-solid-svg-icons/faRoad";
import { faRobot } from "@fortawesome/free-solid-svg-icons/faRobot";
import { faRocket } from "@fortawesome/free-solid-svg-icons/faRocket";
import { faSailboat } from "@fortawesome/free-solid-svg-icons/faSailboat";
import { faScissors } from "@fortawesome/free-solid-svg-icons/faScissors";
import { faSeedling } from "@fortawesome/free-solid-svg-icons/faSeedling";
import { faShield } from "@fortawesome/free-solid-svg-icons/faShield";
import { faShirt } from "@fortawesome/free-solid-svg-icons/faShirt";
import { faShop } from "@fortawesome/free-solid-svg-icons/faShop";
import { faSnowflake } from "@fortawesome/free-solid-svg-icons/faSnowflake";
import { faSocks } from "@fortawesome/free-solid-svg-icons/faSocks";
import { faSolarPanel } from "@fortawesome/free-solid-svg-icons/faSolarPanel";
import { faSpa } from "@fortawesome/free-solid-svg-icons/faSpa";
import { faSpiral } from "@fortawesome/free-solid-svg-icons/faSpiral";
import { faSquare } from "@fortawesome/free-solid-svg-icons/faSquare";
import { faStarAndCrescent } from "@fortawesome/free-solid-svg-icons/faStarAndCrescent";
import { faStarOfLife } from "@fortawesome/free-solid-svg-icons/faStarOfLife";
import { faSterlingSign } from "@fortawesome/free-solid-svg-icons/faSterlingSign";
import { faSwatchbook } from "@fortawesome/free-solid-svg-icons/faSwatchbook";
import { faTent } from "@fortawesome/free-solid-svg-icons/faTent";
import { faTooth } from "@fortawesome/free-solid-svg-icons/faTooth";
import { faTowerCell } from "@fortawesome/free-solid-svg-icons/faTowerCell";
import { faTractor } from "@fortawesome/free-solid-svg-icons/faTractor";
import { faTrain } from "@fortawesome/free-solid-svg-icons/faTrain";
import { faTree } from "@fortawesome/free-solid-svg-icons/faTree";
import { faTrophy } from "@fortawesome/free-solid-svg-icons/faTrophy";
import { faUmbrella } from "@fortawesome/free-solid-svg-icons/faUmbrella";
import { faUmbrellaBeach } from "@fortawesome/free-solid-svg-icons/faUmbrellaBeach";
import { faUniversalAccess } from "@fortawesome/free-solid-svg-icons/faUniversalAccess";
import { faUserGraduate } from "@fortawesome/free-solid-svg-icons/faUserGraduate";
import { faUtensils } from "@fortawesome/free-solid-svg-icons/faUtensils";
import { faVault } from "@fortawesome/free-solid-svg-icons/faVault";
import { faWandSparkles } from "@fortawesome/free-solid-svg-icons/faWandSparkles";
import { faWheelchairMove } from "@fortawesome/free-solid-svg-icons/faWheelchairMove";
import { faWorm } from "@fortawesome/free-solid-svg-icons/faWorm";
import { faYenSign } from "@fortawesome/free-solid-svg-icons/faYenSign";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { intersection } from "es-toolkit/compat";
import {
BookmarkedIcon,
BicycleIcon,
AcademicCapIcon,
BeakerIcon,
BuildingBlocksIcon,
BrowserIcon,
CollectionIcon,
CoinsIcon,
CameraIcon,
CarrotIcon,
FlameIcon,
HashtagIcon,
GraphIcon,
InternetIcon,
LibraryIcon,
PlaneIcon,
RamenIcon,
CloudIcon,
CodeIcon,
EditIcon,
EmailIcon,
EyeIcon,
GlobeIcon,
InfoIcon,
IceCreamIcon,
ImageIcon,
LeafIcon,
LightBulbIcon,
MathIcon,
MoonIcon,
NotepadIcon,
TeamIcon,
PadlockIcon,
PaletteIcon,
PromoteIcon,
QuestionMarkIcon,
SportIcon,
SunIcon,
ShapesIcon,
TargetIcon,
TerminalIcon,
ToolsIcon,
VehicleIcon,
WarningIcon,
DatabaseIcon,
SmileyIcon,
LightningIcon,
ClockIcon,
DoneIcon,
FeedbackIcon,
ServerRackIcon,
ThumbsUpIcon,
TruckIcon,
} from "outline-icons";
import * as React from "react";
import styled from "styled-components";
import LetterIcon from "../components/LetterIcon";
type IconMapping = {
component: React.ComponentType<FAProps>;
keywords?: string;
};
type FAProps = {
color?: string;
size?: number;
className?: string;
style?: React.CSSProperties;
children?: React.ReactNode;
};
export class IconLibrary {
/**
* Get the component for a given icon name
*
* @param icon The name of the icon
* @returns The component for the icon
*/
public static getComponent(icon: string) {
return this.mapping[icon].component;
}
/**
* Find an icon by keyword. This is useful for searching for an icon based on a user's input.
*
* @param keyword The keyword to search for
* @returns The name of the icon that matches the keyword, or undefined if no match is found
*/
public static findIconByKeyword(keyword: string) {
const keys = Object.keys(this.mapping);
for (const key of keys) {
const icon = this.mapping[key];
const keywords = icon.keywords?.split(" ");
const namewords = keyword.toLocaleLowerCase().split(" ");
const matches = intersection(namewords, keywords);
if (matches.length > 0) {
return key;
}
}
return undefined;
}
/**
* Find icons.
*
* @param query The query to search for
* @returns The icon results.
*/
public static findIcons(query: string) {
return Object.keys(this.mapping)
.map((key) => {
const icon = this.mapping[key];
const keywords = `${icon.keywords ?? ""} ${key}`;
if (keywords.includes(query.toLocaleLowerCase())) {
return key;
}
return undefined;
})
.filter((icon: string | undefined): icon is string => !!icon);
}
/**
* A map of all icons available to end users in the app. This does not include icons that are used
* internally only, which can be imported from `outline-icons` directly.
*/
public static mapping: Record<string, IconMapping> = {
// Internal icons
academicCap: {
component: AcademicCapIcon,
keywords: "learn teach lesson guide tutorial onboarding training",
},
bicycle: {
component: BicycleIcon,
keywords: "bicycle bike cycle",
},
beaker: {
component: BeakerIcon,
keywords: "lab research experiment test",
},
buildingBlocks: {
component: BuildingBlocksIcon,
keywords: "app blocks product prototype",
},
bookmark: {
component: BookmarkedIcon,
keywords: "bookmark",
},
browser: {
component: BrowserIcon,
keywords: "browser web app",
},
collection: {
component: (props) => <CollectionIcon expanded {...props} />,
keywords: "collection",
},
coins: {
component: CoinsIcon,
keywords: "coins money finance sales income revenue cash",
},
camera: {
component: CameraIcon,
keywords: "photo picture",
},
carrot: {
component: CarrotIcon,
keywords: "food vegetable produce",
},
clock: {
component: ClockIcon,
keywords: "time",
},
cloud: {
component: CloudIcon,
keywords: "cloud service aws infrastructure",
},
code: {
component: CodeIcon,
keywords: "developer api code development engineering programming",
},
database: {
component: DatabaseIcon,
keywords: "server ops database",
},
done: {
component: DoneIcon,
keywords: "checkmark success complete finished",
},
email: {
component: EmailIcon,
keywords: "email at",
},
eye: {
component: EyeIcon,
keywords: "eye view",
},
feedback: {
component: FeedbackIcon,
keywords: "faq help support",
},
flame: {
component: FlameIcon,
keywords: "fire flame hot",
},
graph: {
component: GraphIcon,
keywords: "chart analytics data",
},
globe: {
component: GlobeIcon,
keywords: "world translate",
},
hashtag: {
component: HashtagIcon,
keywords: "social media tag",
},
info: {
component: InfoIcon,
keywords: "info information",
},
icecream: {
component: IceCreamIcon,
keywords: "food dessert cone scoop",
},
image: {
component: ImageIcon,
keywords: "image photo picture",
},
internet: {
component: InternetIcon,
keywords: "network global globe world",
},
leaf: {
component: LeafIcon,
keywords: "leaf plant outdoors nature ecosystem climate",
},
library: {
component: LibraryIcon,
keywords: "library collection archive",
},
lightbulb: {
component: LightBulbIcon,
keywords: "lightbulb idea",
},
lightning: {
component: LightningIcon,
keywords: "lightning fast zap",
},
letter: {
component: LetterIcon,
keywords: "letter",
},
math: {
component: MathIcon,
keywords: "math formula",
},
moon: {
component: MoonIcon,
keywords: "night moon dark",
},
notepad: {
component: NotepadIcon,
keywords: "journal notepad write notes",
},
padlock: {
component: PadlockIcon,
keywords: "padlock private security authentication authorization auth",
},
palette: {
component: PaletteIcon,
keywords: "design palette art brand",
},
pencil: {
component: EditIcon,
keywords: "copy writing post blog",
},
plane: {
component: PlaneIcon,
keywords: "airplane travel flight trip vacation",
},
promote: {
component: PromoteIcon,
keywords: "marketing promotion",
},
ramen: {
component: RamenIcon,
keywords: "soup food noodle bowl meal",
},
question: {
component: QuestionMarkIcon,
keywords: "question help support faq",
},
server: {
component: ServerRackIcon,
keywords: "ops infra server",
},
sun: {
component: SunIcon,
keywords: "day sun weather",
},
shapes: {
component: ShapesIcon,
keywords: "blocks toy",
},
sport: {
component: SportIcon,
keywords: "sport outdoor racket game",
},
smiley: {
component: SmileyIcon,
keywords: "emoji smiley happy",
},
target: {
component: TargetIcon,
keywords: "target goal sales",
},
team: {
component: TeamIcon,
keywords: "team building organization office",
},
terminal: {
component: TerminalIcon,
keywords: "terminal code",
},
thumbsup: {
component: ThumbsUpIcon,
keywords: "like social favorite upvote",
},
truck: {
component: TruckIcon,
keywords: "truck transport vehicle",
},
tools: {
component: ToolsIcon,
keywords: "tool settings",
},
vehicle: {
component: VehicleIcon,
keywords: "truck car travel transport",
},
warning: {
component: WarningIcon,
keywords: "warning alert error",
},
// Font awesome
...Object.fromEntries(
[
faBagShopping,
faBook,
faBrush,
faCake,
faCat,
faClapperboard,
faCompactDisc,
faCookieBite,
faCrow,
faCrown,
faCube,
faDna,
faDog,
faDollarSign,
faDisplay,
faDroplet,
faFaceDizzy,
faFaceGrinStars,
faFaceLaugh,
faFaceMeh,
faFaceSmileBeam,
faFaceSmileWink,
faFaceSurprise,
faFeather,
faFish,
faFolderClosed,
faFlaskVial,
faGamepad,
faGauge,
faGem,
faGift,
faHammer,
faHandsClapping,
faHeart,
faIndustry,
faKitMedical,
faLaptop,
faLaptopCode,
faMagnet,
faMap,
faMicrochip,
faMountainSun,
faMugHot,
faNetworkWired,
faNewspaper,
faPaintRoller,
faPassport,
faPaw,
faPenRuler,
faPesoSign,
faPhoneVolume,
faPizzaSlice,
faPrescription,
faPuzzlePiece,
faRainbow,
faRecordVinyl,
faRoad,
faRobot,
faRocket,
faSailboat,
faScissors,
faSeedling,
faShield,
faShirt,
faShop,
faSnowflake,
faSocks,
faSolarPanel,
faSpa,
faStarAndCrescent,
faStarOfLife,
faSterlingSign,
faSwatchbook,
faTent,
faTooth,
faTowerCell,
faTractor,
faTrain,
faTree,
faTrophy,
faUmbrella,
faUmbrellaBeach,
faUniversalAccess,
faUserGraduate,
faUtensils,
faVault,
faWandSparkles,
faWebAwesome,
faWheelchairMove,
faWorm,
faYenSign,
faApple,
faWindows,
faAndroid,
faSquareJs,
faPython,
faXTwitter,
faBluesky,
faGithub,
faGitlab,
faDiscord,
faDocker,
faCodepen,
faDropbox,
faPaypal,
faShopify,
faSwift,
faSlack,
faCircle,
faSquare,
faPentagon,
faHexagon,
faDiamond,
faSpiral,
].map((icon) => [
icon.iconName,
{
component: ({ color, size = 24, className, style }: FAProps) => (
<FontAwesomeWrapper size={size}>
<FontAwesomeIcon
style={{
width: 0.6666666667 * size,
height: 0.6666666667 * size,
...style,
}}
color={color}
icon={icon}
className={className}
/>
</FontAwesomeWrapper>
),
},
])
),
} as const;
}
const FontAwesomeWrapper = styled.span<{ size: number }>`
display: flex;
flex-shrink: 0;
align-items: center;
justify-content: center;
width: ${(props) => props.size}px;
height: ${(props) => props.size}px;
`;