Swap any built-in icon, per instance or app-wide.
Components draw their icons from XiodIcons, which installs with xiod-ui. Every one of them can be replaced: with a component from another icon library, an inline <svg>, or an emoji. There are two ways to do it, and they combine.
Built-in
With IconProvider
To change a single place, pass the part an icon prop. A part with one icon takes icon; a part with several takes named props such as prevIcon / nextIcon or triggerIcon / clearIcon. The value is anything React can render.
1import { X } from "lucide-react";2import { DialogPopup } from "xiod-ui/dialog";34export function SaveDialog() {5 return (6 <DialogPopup closeIcon={<X className="size-4" />}>{/* … */}</DialogPopup>7 );8}A node passed this way renders exactly as given, so give it its own size classes. Pass null to render no icon at all.
Every part that takes an icon lists it in the API Reference on its component page.
To swap an icon across the whole app, wrap it in IconProvider from xiod-ui/icon-provider, keyed by the icon's name. Names you leave out keep the built-in icon.
1"use client";23import { ArrowLeft, ArrowRight, Check, X } from "lucide-react";4import { IconProvider } from "xiod-ui/icon-provider";56export function Providers({ children }: { children: React.ReactNode }) {7 return (8 <IconProvider9 icons={{10 Cancel: X,11 Check,12 ChevronLeft: ArrowLeft,13 ChevronRight: ArrowRight,14 }}15 >16 {children}17 </IconProvider>18 );19}Pass components here, not elements (Check, not <Check />). Each XiodUI component then renders your icon with the size and colour classes it would have given its own, so the replacement fits without extra styling.
Providers nest. An inner one is merged over the outer one, so a section of the app can change a single icon without restating the rest.
IconProvider.FileUpload's file-type icons and AgentSteps' status icons are chosen from the content (the file's type, the step's status), so change those through the provider rather than a prop.
The names IconProvider accepts, exported as the IconName type:
| Group | Names |
|---|---|
| Navigation | ChevronUp, ChevronDown, ChevronLeft, ChevronRight, ChevronFirst, ChevronLast, ArrowRight, UnfoldMore, MoreHorizontal |
| Status | Check, CheckmarkCircle, Alert, AlertCircle, InformationCircle, LoadingSpinner, SecurityCheck |
| Actions | Cancel, Copy, Delete, Pencil, Search, PlusSign, MinusSign, Eye, EyeOff, Dropper, Zap, Terminal |
| Files | File, FileEmpty, FileArchive, FileAudio, FileCode, FileImage, FileVideo |
| Layout | GripHorizontal, GripVertical, ViewSidebarLeft, ArrowExpandDiagonalUpRight, ArrowShrinkDiagonalUpRight |
| Other | Calendar, CreditCard |
A component of your own can honour the same overrides. IconSlot renders one icon the way the library's components do: the icon prop first, then the provider, then the fallback you give it.
1import { ChevronRight } from "xiod-icons";2import { Button } from "xiod-ui/button";3import { IconSlot } from "xiod-ui/icon-provider";45export function NextButton({ icon }: { icon?: React.ReactNode }) {6 return (7 <Button variant="outline">8 Next9 <IconSlot name="ChevronRight" fallback={ChevronRight} icon={icon} />10 </Button>11 );12}For the component alone, useIcon(name, fallback) returns the one in effect.