🚧 Under development — suggestions for new items are always welcome! ✨

Icon Field

A field in Payload CMS that lets editors choose a Lucide icon from a dropdown with a live preview.

icon field


Install

pnpm dlx [email protected] add https://p.livog.com/r/icon-field.json

Code

import type { SelectField } from 'payload'
import iconNodes from 'lucide-static/icon-nodes.json'

export type IconOption = {
  value: string
  label: string
}

export type IconField = (overrides?: Partial<SelectField>) => SelectField

const iconField: IconField = (overrides = {}) => {
  const baseField = {
    name: 'icon',
    ...overrides,
    type: 'select',
    interfaceName: 'LucideIcon',
    required: false,
    hasMany: false,
    options: Object.keys(iconNodes).map((slug) => {
      const label = slug
        .split('-')
        .map((segment) => {
          if (/^\d+$/.test(segment)) return segment

          return segment
            .replace(/^[a-z]/, (c) => c.toUpperCase())
            .replace(/(\d)([a-z])/g, (_, d, l) => d + l.toUpperCase())
        })
        .join(' ')

      return {
        value: slug,
        label
      }
    }),
    admin: {
      ...overrides.admin,
      components: {
        ...overrides.admin?.components,
        Field: {
          path: '@/payload/fields/icon/component#IconComponent'
        }
      }
    }
  } as SelectField

  return baseField
}

export { iconField } 

Usage

Add an icon picker to any collection or global:

import { iconField } from '@/payload/fields/icon'

export const Category: CollectionConfig = {
  slug: 'categories',
  fields: [
    { name: 'title', type: 'text', required: true },
    iconField(), // adds an “icon” select powered by Lucide
  ],
}

Example

import { Container } from '@/components/container'
import { DynamicIcon } from 'lucide-react/dynamic';
import { Section } from '@/components/section'

export default function IconFieldDemo() {
  return (
    <Section spacing="xxsmall">
      <Container>
        <div className="grid grid-cols-5 items-center justify-items-center gap-4 p-8">
          <DynamicIcon name="home" className="size-10" />
          <DynamicIcon name="settings" className="size-10" />
          <DynamicIcon name="user" className="size-10" />
          <DynamicIcon name="arrow-down-0-1" className="size-10" />
          <DynamicIcon name="axis-3d" className="size-10" />
        </div>
      </Container>
    </Section>
  )
}
The icon field stores the values specified in name.