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",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify/react": "^6.0.2",
|
"@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-dialog": "^1.1.15",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||||
"@radix-ui/react-label": "^2.1.8",
|
"@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=="],
|
"@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/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=="],
|
"@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify/react": "^6.0.2",
|
"@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-dialog": "^1.1.15",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||||
"@radix-ui/react-label": "^2.1.8",
|
"@radix-ui/react-label": "^2.1.8",
|
||||||
@@ -18,6 +19,7 @@
|
|||||||
"@radix-ui/react-select": "^2.2.6",
|
"@radix-ui/react-select": "^2.2.6",
|
||||||
"@radix-ui/react-slot": "^1.2.4",
|
"@radix-ui/react-slot": "^1.2.4",
|
||||||
"@radix-ui/react-tabs": "^1.1.13",
|
"@radix-ui/react-tabs": "^1.1.13",
|
||||||
|
"@sprint/shared": "workspace:*",
|
||||||
"@tailwindcss/vite": "^4.1.18",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
"@tauri-apps/api": "^2",
|
"@tauri-apps/api": "^2",
|
||||||
"@tauri-apps/plugin-opener": "^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 { useState } from "react";
|
||||||
import LogOutButton from "@/components/log-out-button";
|
import LogOutButton from "@/components/log-out-button";
|
||||||
|
import ThemeToggle from "@/components/theme-toggle";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import ColourPicker from "@/components/ui/colour-picker";
|
import ColourPicker from "@/components/ui/colour-picker";
|
||||||
|
import Icon, { iconNames, iconStyles } from "@/components/ui/icon";
|
||||||
|
|
||||||
function Test() {
|
function Test() {
|
||||||
const [colour, setColour] = useState("#e05656");
|
const [colour, setColour] = useState("#e05656");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="w-full h-[100vh] flex flex-col items-center justify-center gap-4 p-4">
|
<main className="w-full min-h-[100vh] flex justify-center items-center gap-32 p-4">
|
||||||
<h1 className="text-3xl font-bold">Test</h1>
|
<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} />
|
||||||
|
|
||||||
<p className="text-muted-foreground">Simple test page for demo</p>
|
<ThemeToggle />
|
||||||
<div className="flex gap-4">
|
|
||||||
<Button linkTo="/">go back to "/"</Button>
|
|
||||||
</div>
|
</div>
|
||||||
<LogOutButton />
|
|
||||||
|
|
||||||
<ColourPicker colour={colour} onChange={setColour} />
|
<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>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user