feat(icons): add brand icon picker from dashboard-icons
Add a second tab in the node Icon picker to choose from the ~2250 brand icons hosted by homarr-labs/dashboard-icons (Plex, Sonarr, Home Assistant, etc.) served via jsDelivr CDN. The Generic tab keeps the existing lucide picker unchanged. Storage uses a 'brand:<slug>' prefix on custom_icon, so existing nodes referencing lucide keys keep working with zero migration. A new resolveCustomIcon helper returns a discriminated union (lucide | brand) and a NodeIcon component centralizes rendering for both kinds. Includes a manifest fetch script (scripts/fetch-dashboard-icons.mjs) and a checked-in dashboardIcons.json snapshot.
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { createElement } from 'react'
|
||||
import type { LucideIcon } from 'lucide-react'
|
||||
import { resolveCustomIcon, brandIconUrl, isBrandIconKey } from '@/utils/nodeIcons'
|
||||
|
||||
interface NodeIconProps {
|
||||
/** Default icon for the node type (lucide). Used when no customIconKey or unknown key. */
|
||||
typeIcon: LucideIcon
|
||||
/** Optional override key. Legacy lucide keys or `brand:<slug>` for dashboard-icons. */
|
||||
customIconKey?: string
|
||||
size?: number
|
||||
className?: string
|
||||
/** Optional inline color (lucide only — ignored for brand icons). */
|
||||
color?: string
|
||||
}
|
||||
|
||||
export function NodeIcon({ typeIcon, customIconKey, size = 16, className, color }: NodeIconProps) {
|
||||
const resolved = resolveCustomIcon(customIconKey)
|
||||
if (resolved?.kind === 'brand') {
|
||||
return (
|
||||
<img
|
||||
src={resolved.url}
|
||||
alt={resolved.slug}
|
||||
width={size}
|
||||
height={size}
|
||||
loading="lazy"
|
||||
className={className}
|
||||
style={{ width: size, height: size, objectFit: 'contain' }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
const Icon = resolved?.kind === 'lucide' ? resolved.icon : typeIcon
|
||||
return createElement(Icon, { size, className, color })
|
||||
}
|
||||
|
||||
export { brandIconUrl, isBrandIconKey }
|
||||
Reference in New Issue
Block a user