mirror of
https://github.com/hex248/sprint.git
synced 2026-02-07 18:23:03 +00:00
new Icon component with 3 icon variations
This commit is contained in:
6
bun.lock
6
bun.lock
@@ -39,6 +39,8 @@
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@iconify/react": "^6.0.2",
|
||||
"@nsmr/pixelart-react": "^2.0.0",
|
||||
"@phosphor-icons/react": "^2.1.10",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-label": "^2.1.8",
|
||||
@@ -262,6 +264,10 @@
|
||||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
|
||||
|
||||
"@nsmr/pixelart-react": ["@nsmr/pixelart-react@2.0.0", "", { "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-hD9CeUZp10jemfnBQdN+mAMiIGnzcNDG8DoGcHUAvO6JgN1k7dbWscmY5HBqmWglnHliwcq4cY9ICQzjsaWeqQ=="],
|
||||
|
||||
"@phosphor-icons/react": ["@phosphor-icons/react@2.1.10", "", { "peerDependencies": { "react": ">= 16.8", "react-dom": ">= 16.8" } }, "sha512-vt8Tvq8GLjheAZZYa+YG/pW7HDbov8El/MANW8pOAz4eGxrwhnbfrQZq0Cp4q8zBEu8NIhHdnr+r8thnfRSNYA=="],
|
||||
|
||||
"@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="],
|
||||
|
||||
"@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/react": "^6.0.2",
|
||||
"@sprint/shared": "workspace:*",
|
||||
"@nsmr/pixelart-react": "^2.0.0",
|
||||
"@phosphor-icons/react": "^2.1.10",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-label": "^2.1.8",
|
||||
@@ -18,6 +19,7 @@
|
||||
"@radix-ui/react-select": "^2.2.6",
|
||||
"@radix-ui/react-slot": "^1.2.4",
|
||||
"@radix-ui/react-tabs": "^1.1.13",
|
||||
"@sprint/shared": "workspace:*",
|
||||
"@tailwindcss/vite": "^4.1.18",
|
||||
"@tauri-apps/api": "^2",
|
||||
"@tauri-apps/plugin-opener": "^2",
|
||||
|
||||
176
packages/frontend/src/components/ui/icon.tsx
Normal file
176
packages/frontend/src/components/ui/icon.tsx
Normal file
@@ -0,0 +1,176 @@
|
||||
import {
|
||||
Alert as PixelAlert,
|
||||
Check as PixelCheck,
|
||||
ChevronDown as PixelChevronDown,
|
||||
ChevronLeft as PixelChevronLeft,
|
||||
ChevronRight as PixelChevronRight,
|
||||
ChevronUp as PixelChevronUp,
|
||||
Circle as PixelCircle,
|
||||
Clock as PixelClock,
|
||||
Close as PixelClose,
|
||||
Edit as PixelEdit,
|
||||
Home as PixelHome,
|
||||
InfoBox as PixelInfo,
|
||||
Link as PixelLink,
|
||||
Loader as PixelLoader,
|
||||
Logout as PixelLogout,
|
||||
Moon as PixelMoon,
|
||||
MoreVertical as PixelMoreVertical,
|
||||
NoteDelete as PixelNoteDelete,
|
||||
Plus as PixelPlus,
|
||||
Server as PixelServer,
|
||||
Sun as PixelSun,
|
||||
Trash as PixelTrash,
|
||||
Undo as PixelUndo,
|
||||
User as PixelUser,
|
||||
ViewportWide as PixelViewportWide,
|
||||
} from "@nsmr/pixelart-react";
|
||||
import {
|
||||
CheckIcon as PhosphorCheck,
|
||||
CheckCircleIcon as PhosphorCheckCircle,
|
||||
CaretDownIcon as PhosphorChevronDown,
|
||||
CaretLeftIcon as PhosphorChevronLeft,
|
||||
CaretRightIcon as PhosphorChevronRight,
|
||||
CaretUpIcon as PhosphorChevronUp,
|
||||
CircleIcon as PhosphorCircle,
|
||||
ClockIcon as PhosphorClock,
|
||||
DotsSixVerticalIcon as PhosphorDotsSixVertical,
|
||||
DotsThreeVerticalIcon as PhosphorDotsThreeVertical,
|
||||
PencilSimpleIcon as PhosphorEdit,
|
||||
HashIcon as PhosphorHash,
|
||||
HashStraightIcon as PhosphorHashStraight,
|
||||
HouseIcon as PhosphorHome,
|
||||
InfoIcon as PhosphorInfo,
|
||||
LinkIcon as PhosphorLink,
|
||||
SpinnerGapIcon as PhosphorLoader,
|
||||
SignOutIcon as PhosphorLogOut,
|
||||
MoonIcon as PhosphorMoon,
|
||||
OctagonIcon as PhosphorOctagon,
|
||||
PlusIcon as PhosphorPlus,
|
||||
QuestionIcon as PhosphorQuestion,
|
||||
HardDrivesIcon as PhosphorServer,
|
||||
SunIcon as PhosphorSun,
|
||||
TrashIcon as PhosphorTrash,
|
||||
ArrowCounterClockwiseIcon as PhosphorUndo,
|
||||
UserIcon as PhosphorUser,
|
||||
WarningIcon as PhosphorWarning,
|
||||
XIcon as PhosphorX,
|
||||
} from "@phosphor-icons/react";
|
||||
import {
|
||||
AlertTriangle,
|
||||
Check,
|
||||
CheckIcon,
|
||||
ChevronDown,
|
||||
ChevronDownIcon,
|
||||
ChevronLeftIcon,
|
||||
ChevronRightIcon,
|
||||
ChevronUp,
|
||||
ChevronUpIcon,
|
||||
CircleCheckIcon,
|
||||
CircleIcon,
|
||||
CircleQuestionMark,
|
||||
Edit,
|
||||
EllipsisVertical,
|
||||
GripVerticalIcon,
|
||||
Hash,
|
||||
InfoIcon,
|
||||
Link,
|
||||
Loader,
|
||||
Loader2Icon,
|
||||
LogOut,
|
||||
Home as LucideHome,
|
||||
Moon,
|
||||
OctagonXIcon,
|
||||
Plus,
|
||||
ServerIcon,
|
||||
Sun,
|
||||
Timer,
|
||||
Trash,
|
||||
TriangleAlertIcon,
|
||||
Undo,
|
||||
Undo2,
|
||||
UserRound,
|
||||
X,
|
||||
} from "lucide-react";
|
||||
|
||||
const icons = {
|
||||
alertTriangle: { lucide: AlertTriangle, pixel: PixelAlert, phosphor: PhosphorWarning },
|
||||
check: { lucide: Check, pixel: PixelCheck, phosphor: PhosphorCheck },
|
||||
checkIcon: { lucide: CheckIcon, pixel: PixelCheck, phosphor: PhosphorCheck },
|
||||
chevronDown: { lucide: ChevronDown, pixel: PixelChevronDown, phosphor: PhosphorChevronDown },
|
||||
chevronDownIcon: { lucide: ChevronDownIcon, pixel: PixelChevronDown, phosphor: PhosphorChevronDown },
|
||||
chevronLeftIcon: { lucide: ChevronLeftIcon, pixel: PixelChevronLeft, phosphor: PhosphorChevronLeft },
|
||||
chevronRightIcon: { lucide: ChevronRightIcon, pixel: PixelChevronRight, phosphor: PhosphorChevronRight },
|
||||
chevronUp: { lucide: ChevronUp, pixel: PixelChevronUp, phosphor: PhosphorChevronUp },
|
||||
chevronUpIcon: { lucide: ChevronUpIcon, pixel: PixelChevronUp, phosphor: PhosphorChevronUp },
|
||||
circleCheckIcon: { lucide: CircleCheckIcon, pixel: PixelCheck, phosphor: PhosphorCheckCircle },
|
||||
circleIcon: { lucide: CircleIcon, pixel: PixelCircle, phosphor: PhosphorCircle },
|
||||
circleQuestionMark: { lucide: CircleQuestionMark, pixel: PixelNoteDelete, phosphor: PhosphorQuestion },
|
||||
edit: { lucide: Edit, pixel: PixelEdit, phosphor: PhosphorEdit },
|
||||
ellipsisVertical: {
|
||||
lucide: EllipsisVertical,
|
||||
pixel: PixelMoreVertical,
|
||||
phosphor: PhosphorDotsThreeVertical,
|
||||
},
|
||||
gripVerticalIcon: {
|
||||
lucide: GripVerticalIcon,
|
||||
pixel: PixelViewportWide,
|
||||
phosphor: PhosphorDotsSixVertical,
|
||||
},
|
||||
hash: { lucide: Hash, pixel: PhosphorHashStraight, phosphor: PhosphorHash },
|
||||
home: { lucide: LucideHome, pixel: PixelHome, phosphor: PhosphorHome },
|
||||
infoIcon: { lucide: InfoIcon, pixel: PixelInfo, phosphor: PhosphorInfo },
|
||||
link: { lucide: Link, pixel: PixelLink, phosphor: PhosphorLink },
|
||||
loader: { lucide: Loader, pixel: PixelLoader, phosphor: PhosphorLoader },
|
||||
loader2Icon: { lucide: Loader2Icon, pixel: PixelLoader, phosphor: PhosphorLoader },
|
||||
logOut: { lucide: LogOut, pixel: PixelLogout, phosphor: PhosphorLogOut },
|
||||
moon: { lucide: Moon, pixel: PixelMoon, phosphor: PhosphorMoon },
|
||||
octagonXIcon: { lucide: OctagonXIcon, pixel: PixelClose, phosphor: PhosphorOctagon },
|
||||
plus: { lucide: Plus, pixel: PixelPlus, phosphor: PhosphorPlus },
|
||||
serverIcon: { lucide: ServerIcon, pixel: PixelServer, phosphor: PhosphorServer },
|
||||
sun: { lucide: Sun, pixel: PixelSun, phosphor: PhosphorSun },
|
||||
timer: { lucide: Timer, pixel: PixelClock, phosphor: PhosphorClock },
|
||||
trash: { lucide: Trash, pixel: PixelTrash, phosphor: PhosphorTrash },
|
||||
triangleAlertIcon: { lucide: TriangleAlertIcon, pixel: PixelAlert, phosphor: PhosphorWarning },
|
||||
undo: { lucide: Undo, pixel: PixelUndo, phosphor: PhosphorUndo },
|
||||
undo2: { lucide: Undo2, pixel: PixelUndo, phosphor: PhosphorUndo },
|
||||
userRound: { lucide: UserRound, pixel: PixelUser, phosphor: PhosphorUser },
|
||||
x: { lucide: X, pixel: PixelClose, phosphor: PhosphorX },
|
||||
};
|
||||
|
||||
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 default function Icon({
|
||||
icon,
|
||||
iconStyle = "lucide",
|
||||
size = 24,
|
||||
...props
|
||||
}: {
|
||||
icon: IconName;
|
||||
iconStyle?: IconStyle;
|
||||
size?: number | string;
|
||||
color?: string;
|
||||
} & React.ComponentProps<"svg">) {
|
||||
const IconComponent = icons[icon]?.[iconStyle];
|
||||
|
||||
if (!IconComponent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<IconComponent
|
||||
size={size}
|
||||
fill={
|
||||
(iconStyle === "pixel" && icon === "moon") ||
|
||||
(iconStyle === "pixel" && icon === "hash") ||
|
||||
iconStyle === "phosphor"
|
||||
? "var(--foreground)"
|
||||
: "transparent"
|
||||
}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -1,22 +1,59 @@
|
||||
import { useState } from "react";
|
||||
import LogOutButton from "@/components/log-out-button";
|
||||
import ThemeToggle from "@/components/theme-toggle";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import ColourPicker from "@/components/ui/colour-picker";
|
||||
import Icon, { iconNames, iconStyles } from "@/components/ui/icon";
|
||||
|
||||
function Test() {
|
||||
const [colour, setColour] = useState("#e05656");
|
||||
|
||||
return (
|
||||
<main className="w-full h-[100vh] flex flex-col items-center justify-center gap-4 p-4">
|
||||
<h1 className="text-3xl font-bold">Test</h1>
|
||||
|
||||
<p className="text-muted-foreground">Simple test page for demo</p>
|
||||
<main className="w-full min-h-[100vh] flex justify-center items-center gap-32 p-4">
|
||||
<div className="mt-8 flex flex-col items-center gap-4">
|
||||
<p className="text-muted-foreground">Other test components</p>
|
||||
<div className="flex gap-4">
|
||||
<Button linkTo="/">go back to "/"</Button>
|
||||
</div>
|
||||
<LogOutButton />
|
||||
|
||||
<ColourPicker colour={colour} onChange={setColour} />
|
||||
|
||||
<ThemeToggle />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold">Icon Demo</h1>
|
||||
<p className="text-muted-foreground">
|
||||
All {iconNames.length} icons across {iconStyles.length} styles
|
||||
</p>
|
||||
|
||||
<div className="overflow-x-auto">
|
||||
<table className="border-collapse">
|
||||
<thead>
|
||||
<tr className="border-b">
|
||||
<th className="text-left p-2 font-medium">Name</th>
|
||||
{iconStyles.map((iconStyle) => (
|
||||
<th key={iconStyle} className="text-center p-2 font-medium capitalize">
|
||||
{iconStyle}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{iconNames.map((name) => (
|
||||
<tr key={name} className="border-b hover:bg-muted/50">
|
||||
<td className="font-mono text-sm pl-2 pr-12">{name}</td>
|
||||
{iconStyles.map((iconStyle) => (
|
||||
<td key={iconStyle} className="p-2 text-center">
|
||||
<Icon icon={name} iconStyle={iconStyle} size={24} />
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user