mirror of
https://github.com/hex248/sprint.git
synced 2026-02-08 18:33:01 +00:00
use Icon component
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import type { SprintRecord } from "@sprint/shared";
|
||||
import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
|
||||
import * as React from "react";
|
||||
import { type DayButton, DayPicker, getDefaultClassNames } from "react-day-picker";
|
||||
import { Button, buttonVariants } from "@/components/ui/button";
|
||||
import Icon from "@/components/ui/icon";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
function Calendar({
|
||||
@@ -109,14 +109,16 @@ function Calendar({
|
||||
},
|
||||
Chevron: ({ className, orientation, ...props }) => {
|
||||
if (orientation === "left") {
|
||||
return <ChevronLeftIcon className={cn("size-4", className)} {...props} />;
|
||||
return <Icon icon="chevronLeftIcon" className={cn("size-4", className)} {...props} />;
|
||||
}
|
||||
|
||||
if (orientation === "right") {
|
||||
return <ChevronRightIcon className={cn("size-4", className)} {...props} />;
|
||||
return (
|
||||
<Icon icon="chevronRightIcon" className={cn("size-4", className)} {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
return <ChevronDownIcon className={cn("size-4", className)} {...props} />;
|
||||
return <Icon icon="chevronDownIcon" className={cn("size-4", className)} {...props} />;
|
||||
},
|
||||
DayButton: (props) => <CalendarDayButton {...props} sprints={sprints} isEnd={isEnd} />,
|
||||
WeekNumber: ({ children, ...props }) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||
import { XIcon } from "lucide-react";
|
||||
import type * as React from "react";
|
||||
import Icon from "@/components/ui/icon";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -71,7 +71,7 @@ function DialogContent({
|
||||
"[&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||
)}
|
||||
>
|
||||
<XIcon />
|
||||
<Icon icon="x" />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
)}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
||||
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
|
||||
import type * as React from "react";
|
||||
import Icon from "@/components/ui/icon";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
function DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
|
||||
@@ -136,7 +136,7 @@ function DropdownMenuCheckboxItem({
|
||||
>
|
||||
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.ItemIndicator>
|
||||
<CheckIcon className="size-4" />
|
||||
<Icon icon="checkIcon" className="size-4" />
|
||||
</DropdownMenuPrimitive.ItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
@@ -168,7 +168,7 @@ function DropdownMenuRadioItem({
|
||||
>
|
||||
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.ItemIndicator>
|
||||
<CircleIcon className="size-2 fill-current" />
|
||||
<Icon icon="circleIcon" className="size-2 fill-current" />
|
||||
</DropdownMenuPrimitive.ItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
@@ -242,7 +242,7 @@ function DropdownMenuSubTrigger({
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<ChevronRightIcon className="ml-auto size-4" />
|
||||
<Icon icon="chevronRightIcon" className="ml-auto size-4" />
|
||||
</DropdownMenuPrimitive.SubTrigger>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ import {
|
||||
WarningIcon as PhosphorWarning,
|
||||
XIcon as PhosphorX,
|
||||
} from "@phosphor-icons/react";
|
||||
import type { IconStyle } from "@sprint/shared";
|
||||
import {
|
||||
AlertTriangle,
|
||||
Check,
|
||||
@@ -92,6 +93,7 @@ import {
|
||||
UserRound,
|
||||
X,
|
||||
} from "lucide-react";
|
||||
import { useSessionSafe } from "@/components/session-provider";
|
||||
|
||||
const icons = {
|
||||
alertTriangle: { lucide: AlertTriangle, pixel: PixelAlert, phosphor: PhosphorWarning },
|
||||
@@ -141,11 +143,11 @@ const icons = {
|
||||
export type IconName = keyof typeof icons;
|
||||
export const iconNames = Object.keys(icons) as IconName[];
|
||||
export const iconStyles = ["lucide", "pixel", "phosphor"] as const;
|
||||
export type IconStyle = (typeof iconStyles)[number];
|
||||
export type { IconStyle };
|
||||
|
||||
export default function Icon({
|
||||
icon,
|
||||
iconStyle = "lucide",
|
||||
iconStyle,
|
||||
size = 24,
|
||||
...props
|
||||
}: {
|
||||
@@ -154,7 +156,9 @@ export default function Icon({
|
||||
size?: number | string;
|
||||
color?: string;
|
||||
} & React.ComponentProps<"svg">) {
|
||||
const IconComponent = icons[icon]?.[iconStyle];
|
||||
const session = useSessionSafe();
|
||||
const resolvedStyle = (iconStyle ?? session?.user?.iconPreference ?? "lucide") as IconStyle;
|
||||
const IconComponent = icons[icon]?.[resolvedStyle];
|
||||
|
||||
if (!IconComponent) {
|
||||
return null;
|
||||
@@ -164,9 +168,9 @@ export default function Icon({
|
||||
<IconComponent
|
||||
size={size}
|
||||
fill={
|
||||
(iconStyle === "pixel" && icon === "moon") ||
|
||||
(iconStyle === "pixel" && icon === "hash") ||
|
||||
iconStyle === "phosphor"
|
||||
(resolvedStyle === "pixel" && icon === "moon") ||
|
||||
(resolvedStyle === "pixel" && icon === "hash") ||
|
||||
resolvedStyle === "phosphor"
|
||||
? "var(--foreground)"
|
||||
: "transparent"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Hash } from "lucide-react";
|
||||
import type * as React from "react";
|
||||
import Icon from "@/components/ui/icon";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
function Input({
|
||||
@@ -25,7 +25,7 @@ function Input({
|
||||
>
|
||||
{showHashPrefix && (
|
||||
<span className="border-r px-1 py-1 text-muted-foreground">
|
||||
<Hash className="size-3.5" strokeWidth={1.5} />
|
||||
<Icon icon="hash" className="size-3.5" />
|
||||
</span>
|
||||
)}
|
||||
<input
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { GripVerticalIcon } from "lucide-react";
|
||||
import type * as React from "react";
|
||||
import { Group, Panel, Separator } from "react-resizable-panels";
|
||||
import Icon from "@/components/ui/icon";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -49,7 +49,7 @@ function ResizableSeparator({
|
||||
>
|
||||
{withHandle && (
|
||||
<div className="bg-border z-10 flex h-4 w-3 items-center justify-center rounded-xs border">
|
||||
<GripVerticalIcon className="size-2.5" />
|
||||
<Icon icon="gripVerticalIcon" className="size-2.5" />
|
||||
</div>
|
||||
)}
|
||||
</Separator>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as SelectPrimitive from "@radix-ui/react-select";
|
||||
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
|
||||
import type * as React from "react";
|
||||
import Icon from "@/components/ui/icon";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -72,8 +72,9 @@ function SelectTrigger({
|
||||
)}
|
||||
{children}
|
||||
<SelectPrimitive.Icon asChild>
|
||||
<ChevronDownIcon
|
||||
className={cn("size-4 opacity-50", chevronClassName)}
|
||||
<Icon
|
||||
icon="chevronDownIcon"
|
||||
className={cn("size-4.5 opacity-50", chevronClassName)}
|
||||
style={{ rotate: isOpen ? "180deg" : "0deg" }}
|
||||
/>
|
||||
</SelectPrimitive.Icon>
|
||||
@@ -165,7 +166,7 @@ function SelectItem({
|
||||
className="absolute right-2 flex size-3.5 items-center justify-center"
|
||||
>
|
||||
<SelectPrimitive.ItemIndicator>
|
||||
<CheckIcon className="size-4" />
|
||||
<Icon icon="checkIcon" className="size-4" />
|
||||
</SelectPrimitive.ItemIndicator>
|
||||
</span>
|
||||
{textClassName ? (
|
||||
@@ -197,7 +198,7 @@ function SelectScrollUpButton({
|
||||
className={cn("flex cursor-default items-center justify-center py-1", className)}
|
||||
{...props}
|
||||
>
|
||||
<ChevronUpIcon className="size-4" />
|
||||
<Icon icon="chevronUpIcon" className="size-4" />
|
||||
</SelectPrimitive.ScrollUpButton>
|
||||
);
|
||||
}
|
||||
@@ -212,7 +213,7 @@ function SelectScrollDownButton({
|
||||
className={cn("flex cursor-default items-center justify-center py-1", className)}
|
||||
{...props}
|
||||
>
|
||||
<ChevronDownIcon className="size-4" />
|
||||
<Icon icon="chevronDownIcon" className="size-4" />
|
||||
</SelectPrimitive.ScrollDownButton>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CircleCheckIcon, InfoIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon } from "lucide-react";
|
||||
import { useTheme } from "next-themes";
|
||||
import { Toaster as Sonner, type ToasterProps } from "sonner";
|
||||
import Icon from "@/components/ui/icon";
|
||||
|
||||
const Toaster = ({ ...props }: ToasterProps) => {
|
||||
const { theme = "system" } = useTheme();
|
||||
@@ -10,11 +10,11 @@ const Toaster = ({ ...props }: ToasterProps) => {
|
||||
theme={theme as ToasterProps["theme"]}
|
||||
className="toaster group"
|
||||
icons={{
|
||||
success: <CircleCheckIcon className="size-4" />,
|
||||
info: <InfoIcon className="size-4" />,
|
||||
warning: <TriangleAlertIcon className="size-4" />,
|
||||
error: <OctagonXIcon className="size-4" />,
|
||||
loading: <Loader2Icon className="size-4 animate-spin" />,
|
||||
success: <Icon icon="circleCheckIcon" className="size-4" />,
|
||||
info: <Icon icon="infoIcon" className="size-4" />,
|
||||
warning: <Icon icon="triangleAlertIcon" className="size-4" />,
|
||||
error: <Icon icon="octagonXIcon" className="size-4" />,
|
||||
loading: <Icon icon="loader2Icon" className="size-4 animate-spin" />,
|
||||
}}
|
||||
style={
|
||||
{
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Loader } from "lucide-react";
|
||||
|
||||
import Icon from "@/components/ui/icon";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
function Spinner({ className, ...props }: React.ComponentProps<"svg">) {
|
||||
return (
|
||||
<Loader
|
||||
<Icon
|
||||
icon="loader"
|
||||
role="status"
|
||||
aria-label="Loading"
|
||||
className={cn("size-4 animate-spin", className)}
|
||||
|
||||
Reference in New Issue
Block a user