Last active
April 28, 2025 15:56
-
-
Save mommaroodles/db53ce4ac18427b738d867cd9cce47f7 to your computer and use it in GitHub Desktop.
PayloadCMS - Add Icon Select to Blocks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| My Implementation of adding a Select Icon Field to Blocks is quite simple. I add icons on demand as and when I need them instead of having the entire Icon Libary. | |
| My PayloadCMS version: 3.35.1 | |
| Next.JS: 15.3.1 | |
| I'm using the PayloadCMS web site template. | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // src/blocks/CoreFeatures/component.tsx | |
| import React from 'react' | |
| import { RenderIcon, IconName } from '@/components/Icons' | |
| interface CoreFeaturesBlockProps { | |
| heading?: string | |
| subheading?: string | |
| features: { | |
| icon: IconName | |
| title: string | |
| description: string | |
| id?: string | |
| }[] | |
| } | |
| export const CoreFeatures: React.FC<CoreFeaturesBlockProps> = ({ | |
| heading = 'Our Core Features', | |
| subheading = 'Features', | |
| features = [], | |
| }) => ( | |
| <section className="py-24"> | |
| <div className="container mx-auto max-w-screen-xl"> | |
| {subheading && <p className="mb-4 text-xs text-muted-foreground md:pl-5">{subheading}</p>} | |
| <h2 className="text-3xl font-medium md:pl-5 lg:text-4xl">{heading}</h2> | |
| <div className="mx-auto mt-14 grid gap-x-10 gap-y-8 md:grid-cols-2 lg:grid-cols-3"> | |
| {features.map((feature) => ( | |
| <div | |
| className="flex flex-col items-start gap-4 rounded-lg bg-card p-6 shadow-sm" | |
| key={feature.id || feature.title} | |
| > | |
| <span className="mb-4 flex size-12 items-center justify-center rounded-full bg-accent"> | |
| <RenderIcon name={feature.icon} className="size-5 md:size-7" /> | |
| </span> | |
| <h3 className="font-medium text-lg">{feature.title}</h3> | |
| <p className="text-sm text-muted-foreground">{feature.description}</p> | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| </section> | |
| ) | |
| export default CoreFeatures |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // src/blocks/CoreFeatures/config.tsx | |
| import type { Block } from 'payload' | |
| import { availableIcons } from '@/components/Icons' | |
| export type FeatureIconType = (typeof availableIcons)[number]['value'] | |
| export const CoreFeaturesBlock: Block = { | |
| slug: 'corefeatures', | |
| labels: { | |
| singular: 'Core Feature', | |
| plural: 'Core Features', | |
| }, | |
| fields: [ | |
| { | |
| name: 'heading', | |
| label: 'Heading', | |
| type: 'text', | |
| required: true, | |
| defaultValue: 'Core Features', | |
| }, | |
| { | |
| name: 'subheading', | |
| label: 'Subheading', | |
| type: 'text', | |
| required: false, | |
| defaultValue: 'Features', | |
| }, | |
| { | |
| name: 'features', | |
| label: 'Features', | |
| type: 'array', | |
| minRows: 1, | |
| maxRows: 12, | |
| required: true, | |
| fields: [ | |
| { | |
| name: 'icon', | |
| label: 'Icon', | |
| type: 'select', | |
| required: true, | |
| options: [...availableIcons], | |
| }, | |
| { | |
| name: 'title', | |
| label: 'Title', | |
| type: 'text', | |
| required: true, | |
| }, | |
| { | |
| name: 'description', | |
| label: 'Description', | |
| type: 'textarea', | |
| required: true, | |
| }, | |
| ], | |
| }, | |
| ], | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //src/components/Icons/index.tsx | |
| import * as Icons from 'lucide-react' | |
| export const iconMap = { | |
| Timer: Icons.Timer, | |
| Zap: Icons.Zap, | |
| ZoomIn: Icons.ZoomIn, | |
| PersonStanding: Icons.PersonStanding, | |
| DollarSign: Icons.DollarSign, | |
| MessagesSquare: Icons.MessagesSquare, | |
| Blocks: Icons.Blocks, | |
| Bot: Icons.Bot, | |
| Film: Icons.Film, | |
| MessageCircle: Icons.MessageCircle, | |
| Settings2: Icons.Settings2, | |
| // Add more icons here | |
| } | |
| export type IconName = keyof typeof iconMap | |
| export const availableIcons = Object.keys(iconMap).map((key) => ({ | |
| label: key.replace(/([A-Z])/g, ' $1').trim(), | |
| value: key as IconName, | |
| })) | |
| export function RenderIcon({ name, className }: { name: IconName; className?: string }) { | |
| const Icon = iconMap[name] | |
| return Icon ? <Icon className={className} /> : null | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment