refactor: migrate all icons from Untitled UI to FontAwesome Pro Duotone

Replace all @untitledui/icons imports across 55 files with equivalent
@fortawesome/pro-duotone-svg-icons icons, using FontAwesomeIcon wrappers
(FC<{ className?: string }>) for prop-based usage and inline replacements
for direct JSX usage. Drops unsupported Untitled UI-specific props
(strokeWidth, numeric size). TypeScript compiles clean with no errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-21 11:07:19 +05:30
parent 3064eeb444
commit 6f40b82579
55 changed files with 289 additions and 120 deletions

View File

@@ -1,5 +1,6 @@
import type { PropsWithChildren } from "react";
import { X as CloseIcon, Menu02 } from "@untitledui/icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faXmark, faBars } from "@fortawesome/pro-duotone-svg-icons";
import {
Button as AriaButton,
Dialog as AriaDialog,
@@ -20,8 +21,8 @@ export const MobileNavigationHeader = ({ children }: PropsWithChildren) => {
aria-label="Expand navigation menu"
className="group flex items-center justify-center rounded-lg bg-primary p-2 text-fg-secondary outline-focus-ring hover:bg-primary_hover hover:text-fg-secondary_hover focus-visible:outline-2 focus-visible:outline-offset-2"
>
<Menu02 className="size-6 transition duration-200 ease-in-out group-aria-expanded:opacity-0" />
<CloseIcon className="absolute size-6 opacity-0 transition duration-200 ease-in-out group-aria-expanded:opacity-100" />
<FontAwesomeIcon icon={faBars} className="size-6 transition duration-200 ease-in-out group-aria-expanded:opacity-0" />
<FontAwesomeIcon icon={faXmark} className="absolute size-6 opacity-0 transition duration-200 ease-in-out group-aria-expanded:opacity-100" />
</AriaButton>
</header>
@@ -42,7 +43,7 @@ export const MobileNavigationHeader = ({ children }: PropsWithChildren) => {
onPress={() => state.close()}
className="fixed top-3 right-2 flex cursor-pointer items-center justify-center rounded-lg p-2 text-fg-white/70 outline-focus-ring hover:bg-white/10 hover:text-fg-white focus-visible:outline-2 focus-visible:outline-offset-2"
>
<CloseIcon className="size-6" />
<FontAwesomeIcon icon={faXmark} className="size-6" />
</AriaButton>
<AriaModal className="w-full cursor-auto will-change-transform">

View File

@@ -1,9 +1,9 @@
import type { FC, HTMLAttributes } from "react";
import { useCallback, useEffect, useRef } from "react";
import type { Placement } from "@react-types/overlays";
import { ChevronSelectorVertical } from "@untitledui/icons";
import { faSort } from "@fortawesome/pro-duotone-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faUser, faGear, faArrowRightFromBracket, faPhoneVolume } from "@fortawesome/pro-duotone-svg-icons";
import { faUser, faGear, faArrowRightFromBracket, faPhoneVolume, faSort } from "@fortawesome/pro-duotone-svg-icons";
const IconUser: FC<{ className?: string }> = ({ className }) => <FontAwesomeIcon icon={faUser} className={className} />;
const IconSettings: FC<{ className?: string }> = ({ className }) => <FontAwesomeIcon icon={faGear} className={className} />;
@@ -154,7 +154,7 @@ export const NavAccountCard = ({
<div className="absolute top-1.5 right-1.5">
<AriaDialogTrigger>
<AriaButton className="flex cursor-pointer items-center justify-center rounded-md p-1.5 text-fg-quaternary outline-focus-ring transition duration-100 ease-linear hover:bg-primary_hover hover:text-fg-quaternary_hover focus-visible:outline-2 focus-visible:outline-offset-2 pressed:bg-primary_hover pressed:text-fg-quaternary_hover">
<ChevronSelectorVertical className="size-4 shrink-0" />
<FontAwesomeIcon icon={faSort} className="size-4 shrink-0" />
</AriaButton>
<AriaPopover
placement={popoverPlacement ?? (isDesktop ? "right bottom" : "top right")}

View File

@@ -1,5 +1,6 @@
import type { FC, HTMLAttributes, MouseEventHandler, ReactNode } from "react";
import { ChevronDown, Share04 } from "@untitledui/icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faChevronDown, faArrowUpRightFromSquare } from "@fortawesome/pro-duotone-svg-icons";
import { Link as AriaLink } from "react-aria-components";
import { Badge } from "@/components/base/badges/badges";
import { cx, sortCx } from "@/utils/cx";
@@ -57,7 +58,7 @@ export const NavItemBase = ({ current, type, badge, href, icon: Icon, children,
);
const isExternal = href && href.startsWith("http");
const externalIcon = isExternal && <Share04 className="size-4 stroke-[2.5px] text-fg-quaternary" />;
const externalIcon = isExternal && <FontAwesomeIcon icon={faArrowUpRightFromSquare} className="size-4 text-fg-quaternary" />;
if (type === "collapsible") {
return (
@@ -68,7 +69,7 @@ export const NavItemBase = ({ current, type, badge, href, icon: Icon, children,
{badgeElement}
<ChevronDown aria-hidden="true" className="ml-3 size-4 shrink-0 stroke-[2.5px] text-fg-quaternary in-open:-scale-y-100" />
<FontAwesomeIcon icon={faChevronDown} aria-hidden="true" className="ml-3 size-4 shrink-0 text-fg-quaternary in-open:-scale-y-100" />
</summary>
);
}