mirror of
				https://github.com/walkxcode/dashboard-icons.git
				synced 2025-10-31 16:57:58 +01:00 
			
		
		
		
	feat(icons): implement theme-aware icon variants in search and details components
This commit is contained in:
		
				
					committed by
					
						 Thomas Camlong
						Thomas Camlong
					
				
			
			
				
	
			
			
			
						parent
						
							bf78bc6a24
						
					
				
				
					commit
					62ab677ee3
				
			| @@ -10,6 +10,7 @@ import Image from "next/image" | ||||
| import Link from "next/link" | ||||
| import { usePathname, useRouter, useSearchParams } from "next/navigation" | ||||
| import { useCallback, useEffect, useRef, useState } from "react" | ||||
| import { useTheme } from "next-themes" | ||||
|  | ||||
| export function IconSearch({ icons }: IconSearchProps) { | ||||
| 	const searchParams = useSearchParams() | ||||
| @@ -18,6 +19,7 @@ export function IconSearch({ icons }: IconSearchProps) { | ||||
| 	const pathname = usePathname() | ||||
| 	const [searchQuery, setSearchQuery] = useState(initialQuery ?? "") | ||||
| 	const timeoutRef = useRef<NodeJS.Timeout | null>(null) | ||||
| 	const { resolvedTheme } = useTheme() | ||||
| 	const [filteredIcons, setFilteredIcons] = useState(() => { | ||||
| 		if (!initialQuery?.trim()) return icons | ||||
|  | ||||
| @@ -79,6 +81,23 @@ export function IconSearch({ icons }: IconSearchProps) { | ||||
| 		} | ||||
| 	}, []) | ||||
|  | ||||
| 	// Helper function to get the appropriate icon variant based on theme | ||||
| 	const getIconVariant = (name: string, data: any) => { | ||||
| 		// Check if the icon has theme variants and use appropriate one | ||||
| 		if (data.colors) { | ||||
| 			// If in dark mode and a light variant exists, use the light variant | ||||
| 			if (resolvedTheme === 'dark' && data.colors.light) { | ||||
| 				return data.colors.light; | ||||
| 			} | ||||
| 			// If in light mode and a dark variant exists, use the dark variant | ||||
| 			else if (resolvedTheme === 'light' && data.colors.dark) { | ||||
| 				return data.colors.dark; | ||||
| 			} | ||||
| 		} | ||||
| 		// Fall back to the default name if no appropriate variant | ||||
| 		return name; | ||||
| 	} | ||||
|  | ||||
| 	if (!searchParams) return null | ||||
|  | ||||
| 	return ( | ||||
| @@ -133,7 +152,7 @@ export function IconSearch({ icons }: IconSearchProps) { | ||||
|  | ||||
| 								<div className="relative h-12 w-12 sm:h-16 sm:w-16 mb-2"> | ||||
| 									<Image | ||||
| 										src={`${BASE_URL}/${data.base}/${name}.${data.base}`} | ||||
| 										src={`${BASE_URL}/${data.base}/${getIconVariant(name, data)}.${data.base}`} | ||||
| 										alt={`${name} icon`} | ||||
| 										fill | ||||
| 										className="object-contain p-1 group-hover:scale-110 transition-transform duration-300" | ||||
|   | ||||
| @@ -13,6 +13,7 @@ import Link from "next/link" | ||||
| import { useState } from "react" | ||||
| import { toast } from "sonner" | ||||
| import { Carbon } from "./carbon" | ||||
| import { useTheme } from "next-themes" | ||||
|  | ||||
| export type IconDetailsProps = { | ||||
| 	icon: string | ||||
| @@ -21,6 +22,7 @@ export type IconDetailsProps = { | ||||
| } | ||||
|  | ||||
| export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) { | ||||
| 	const { resolvedTheme } = useTheme() | ||||
| 	const authorName = authorData.name || authorData.login || "" | ||||
| 	const iconColorVariants = iconData.colors | ||||
| 	const formattedDate = new Date(iconData.update.timestamp).toLocaleDateString("en-GB", { | ||||
| @@ -42,6 +44,23 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) { | ||||
| 	const availableFormats = getAvailableFormats() | ||||
| 	const [copiedVariants, setCopiedVariants] = useState<Record<string, boolean>>({}) | ||||
|  | ||||
| 	// Helper function to get the appropriate icon variant based on theme | ||||
| 	const getIconVariant = (iconName: string) => { | ||||
| 		// Check if the icon has theme variants | ||||
| 		if (iconColorVariants) { | ||||
| 			// If in dark mode and a light variant exists, use the light variant | ||||
| 			if (resolvedTheme === 'dark' && iconColorVariants.light) { | ||||
| 				return iconColorVariants.light; | ||||
| 			} | ||||
| 			// If in light mode and a dark variant exists, use the dark variant | ||||
| 			else if (resolvedTheme === 'light' && iconColorVariants.dark) { | ||||
| 				return iconColorVariants.dark; | ||||
| 			} | ||||
| 		} | ||||
| 		// Fall back to the default name if no appropriate variant | ||||
| 		return iconName; | ||||
| 	} | ||||
|  | ||||
| 	const handleCopy = (url: string, variantKey: string) => { | ||||
| 		navigator.clipboard.writeText(url) | ||||
| 		setCopiedVariants((prev) => ({ | ||||
| @@ -168,7 +187,7 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) { | ||||
| 							<div className="flex flex-col items-center"> | ||||
| 								<div className="relative w-32 h-32 bg-background/90 rounded-xl overflow-hidden border flex items-center justify-center p-3 mb-4"> | ||||
| 									<Image | ||||
| 										src={`${BASE_URL}/${iconData.base}/${icon}.${iconData.base}`} | ||||
| 										src={`${BASE_URL}/${iconData.base}/${getIconVariant(icon)}.${iconData.base}`} | ||||
| 										width={96} | ||||
| 										height={96} | ||||
| 										alt={icon} | ||||
| @@ -332,7 +351,7 @@ export function IconDetails({ icon, iconData, authorData }: IconDetailsProps) { | ||||
| 									<h3 className="text-sm font-semibold text-muted-foreground">Source</h3> | ||||
| 									<Button variant="outline" className="w-full" asChild> | ||||
| 										<Link | ||||
| 											href={`${REPO_PATH}/tree/main/${iconData.base}/${icon}.${iconData.base}`} | ||||
| 											href={`${REPO_PATH}/blob/main/meta/${icon}.json`} | ||||
| 											target="_blank" | ||||
| 											rel="noopener noreferrer" | ||||
| 										> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user