Skip to main content

dioxus_mdx/components/
icons.rs

1//! Icon mapping utilities for MDX components.
2//!
3//! Maps common icon names from Mintlify/FontAwesome style to Lucide icons.
4
5use dioxus::prelude::*;
6use dioxus_free_icons::{Icon, icons::ld_icons::*};
7
8/// Render an icon by name.
9///
10/// Maps common icon names (e.g., "code", "folder", "star") to Lucide icons.
11/// Returns a default icon if the name is not recognized.
12#[component]
13pub fn MdxIcon(
14    /// Icon name (e.g., "code", "brain-circuit", "folder").
15    name: String,
16    /// CSS classes to apply (default: "size-5").
17    #[props(default = "size-5".to_string())]
18    class: String,
19) -> Element {
20    let icon_class = class;
21
22    match name.as_str() {
23        "code" => rsx! { Icon { class: icon_class, icon: LdCode } },
24        "brain-circuit" | "brain" => rsx! { Icon { class: icon_class, icon: LdBrainCircuit } },
25        "folder" => rsx! { Icon { class: icon_class, icon: LdFolder } },
26        "list" => rsx! { Icon { class: icon_class, icon: LdList } },
27        "file" => rsx! { Icon { class: icon_class, icon: LdFile } },
28        "plus" | "plus-circle" => rsx! { Icon { class: icon_class, icon: LdPlus } },
29        "pen" | "pencil" => rsx! { Icon { class: icon_class, icon: LdPencil } },
30        "trash" | "trash-alt" => rsx! { Icon { class: icon_class, icon: LdTrash } },
31        "thumbs-up" => rsx! { Icon { class: icon_class, icon: LdThumbsUp } },
32        "star" => rsx! { Icon { class: icon_class, icon: LdStar } },
33        "chart-bar" | "chart-line" | "chart-simple" => {
34            rsx! { Icon { class: icon_class, icon: LdBarChart } }
35        }
36        "book" => rsx! { Icon { class: icon_class, icon: LdBook } },
37        "puzzle-piece" => rsx! { Icon { class: icon_class, icon: LdPuzzle } },
38        "shield-check" => rsx! { Icon { class: icon_class, icon: LdShieldCheck } },
39        "list-check" => rsx! { Icon { class: icon_class, icon: LdListChecks } },
40        "palette" => rsx! { Icon { class: icon_class, icon: LdPalette } },
41        "rocket" => rsx! { Icon { class: icon_class, icon: LdRocket } },
42        "settings" | "cog" => rsx! { Icon { class: icon_class, icon: LdSettings } },
43        "user-plus" => rsx! { Icon { class: icon_class, icon: LdUserPlus } },
44        "folder-plus" => rsx! { Icon { class: icon_class, icon: LdFolderPlus } },
45        "paste" | "clipboard-paste" => rsx! { Icon { class: icon_class, icon: LdClipboardPaste } },
46        "browser" | "globe" => rsx! { Icon { class: icon_class, icon: LdGlobe } },
47        "cart-shopping" | "shopping-cart" => {
48            rsx! { Icon { class: icon_class, icon: LdShoppingCart } }
49        }
50        "circle-question" | "help" => rsx! { Icon { class: icon_class, icon: LdCircleHelp } },
51        "circle-exclamation" | "alert" => rsx! { Icon { class: icon_class, icon: LdCircleAlert } },
52        "react" | "atom" => rsx! { Icon { class: icon_class, icon: LdAtom } },
53        "vuejs" | "vue" | "component" => rsx! { Icon { class: icon_class, icon: LdComponent } },
54        "angular" | "triangle" => rsx! { Icon { class: icon_class, icon: LdTriangle } },
55        "wordpress" | "pen-tool" => rsx! { Icon { class: icon_class, icon: LdPenTool } },
56        "ghost" => rsx! { Icon { class: icon_class, icon: LdGhost } },
57        "newspaper" => rsx! { Icon { class: icon_class, icon: LdNewspaper } },
58        "github" => rsx! { Icon { class: icon_class, icon: LdGithub } },
59        "shield" => rsx! { Icon { class: icon_class, icon: LdShield } },
60        "key" => rsx! { Icon { class: icon_class, icon: LdKey } },
61        "clock" => rsx! { Icon { class: icon_class, icon: LdClock } },
62        "eye-slash" | "eye-off" => rsx! { Icon { class: icon_class, icon: LdEyeOff } },
63        "arrows-left-right" | "arrow-left-right" => {
64            rsx! { Icon { class: icon_class, icon: LdArrowLeftRight } }
65        }
66        "mobile" | "smartphone" => rsx! { Icon { class: icon_class, icon: LdSmartphone } },
67        "lightbulb" => rsx! { Icon { class: icon_class, icon: LdLightbulb } },
68        "info" => rsx! { Icon { class: icon_class, icon: LdInfo } },
69        "warning" | "triangle-alert" => rsx! { Icon { class: icon_class, icon: LdTriangleAlert } },
70        "check" => rsx! { Icon { class: icon_class, icon: LdCheck } },
71        "copy" => rsx! { Icon { class: icon_class, icon: LdCopy } },
72        "chevron-down" => rsx! { Icon { class: icon_class, icon: LdChevronDown } },
73        "chevron-right" => rsx! { Icon { class: icon_class, icon: LdChevronRight } },
74        "arrow-right" => rsx! { Icon { class: icon_class, icon: LdArrowRight } },
75        // Additional icons for docs
76        "users" | "team" => rsx! { Icon { class: icon_class, icon: LdUsers } },
77        "robot" | "bot" => rsx! { Icon { class: icon_class, icon: LdBot } },
78        "code-branch" | "git-branch" | "branch" => {
79            rsx! { Icon { class: icon_class, icon: LdGitBranch } }
80        }
81        "link" => rsx! { Icon { class: icon_class, icon: LdLink } },
82        "image" | "picture" => rsx! { Icon { class: icon_class, icon: LdImage } },
83        "camera" | "screenshot" => rsx! { Icon { class: icon_class, icon: LdCamera } },
84        "terminal" | "command" => rsx! { Icon { class: icon_class, icon: LdTerminal } },
85        "download" => rsx! { Icon { class: icon_class, icon: LdDownload } },
86        "upload" => rsx! { Icon { class: icon_class, icon: LdUpload } },
87        "database" => rsx! { Icon { class: icon_class, icon: LdDatabase } },
88        "server" => rsx! { Icon { class: icon_class, icon: LdServer } },
89        "cloud" => rsx! { Icon { class: icon_class, icon: LdCloud } },
90        "mail" | "email" | "envelope" => rsx! { Icon { class: icon_class, icon: LdMail } },
91        "lock" | "unlock" => rsx! { Icon { class: icon_class, icon: LdLock } },
92        "search" | "magnifying-glass" => rsx! { Icon { class: icon_class, icon: LdSearch } },
93        "home" | "house" => rsx! { Icon { class: icon_class, icon: LdHome } },
94        "external-link" => rsx! { Icon { class: icon_class, icon: LdExternalLink } },
95        "refresh" | "rotate" => rsx! { Icon { class: icon_class, icon: LdRefreshCw } },
96        "play" => rsx! { Icon { class: icon_class, icon: LdPlay } },
97        "pause" => rsx! { Icon { class: icon_class, icon: LdPause } },
98        "stop" | "square" => rsx! { Icon { class: icon_class, icon: LdSquare } },
99        "message" | "comment" => rsx! { Icon { class: icon_class, icon: LdMessageSquare } },
100        "bell" | "notification" => rsx! { Icon { class: icon_class, icon: LdBell } },
101        "tag" | "label" => rsx! { Icon { class: icon_class, icon: LdTag } },
102        "bookmark" => rsx! { Icon { class: icon_class, icon: LdBookmark } },
103        "heart" | "favorite" => rsx! { Icon { class: icon_class, icon: LdHeart } },
104        "filter" => rsx! { Icon { class: icon_class, icon: LdFilter } },
105        "sort" | "arrow-up-down" => rsx! { Icon { class: icon_class, icon: LdArrowUpDown } },
106        "zap" | "bolt" | "lightning" => rsx! { Icon { class: icon_class, icon: LdZap } },
107        _ => rsx! { Icon { class: icon_class, icon: LdCircle } },
108    }
109}
110
111/// Render a callout-specific icon.
112#[component]
113pub fn CalloutIcon(
114    /// Callout type: "tip", "note", "warning", or "info".
115    callout_type: String,
116    /// CSS classes (default: "size-5").
117    #[props(default = "size-5".to_string())]
118    class: String,
119) -> Element {
120    match callout_type.to_lowercase().as_str() {
121        "tip" => rsx! { Icon { class, icon: LdLightbulb } },
122        "note" => rsx! { Icon { class, icon: LdInfo } },
123        "warning" => rsx! { Icon { class, icon: LdTriangleAlert } },
124        "info" => rsx! { Icon { class, icon: LdInfo } },
125        _ => rsx! { Icon { class, icon: LdInfo } },
126    }
127}