@johnmanitaras/react-icon-picker
v1.1.7
Published
A beautiful, searchable icon picker component with 180+ Lucide React icons
Maintainers
Readme
React Icon Picker
A beautiful, searchable icon picker component built with React, TypeScript, and Tailwind CSS. Features 180+ carefully curated Lucide React icons with intelligent search and category filtering.
Features
- 🎨 Beautiful Design - Modern, accessible interface with smooth animations
- 🔍 Smart Search - Search by icon name, keywords, or category
- 📱 Responsive - Works perfectly on desktop, tablet, and mobile
- ⌨️ Keyboard Support - Full keyboard navigation and shortcuts
- 🏷️ Category Filtering - Browse icons by logical categories
- 🎯 TypeScript - Full type safety and IntelliSense support
- ♿ Accessible - WCAG compliant with proper ARIA labels
- 🚀 Production Ready - Optimized performance and error handling
Installation
npm install @your-username/react-icon-pickerPeer Dependencies
Make sure you have the required peer dependencies installed:
npm install react react-domSetup
1. Import the Component and Styles
import { IconPicker } from '@your-username/react-icon-picker';
import '@your-username/react-icon-picker/styles.css';2. Design System Integration
This component is designed to integrate with your app's existing design system. It uses:
- Your app's colors, typography, and styling for visual consistency
- Layout-isolated classes (
icon-picker-*) for reliable positioning
Required CSS Classes in Your App
The component expects these standard CSS classes to be available in your app:
/* Button styles */
.btn-primary { /* Primary button styling */ }
.btn-secondary { /* Secondary button styling */ }
/* Form elements */
.input { /* Input field styling */ }
/* Card layout */
.card { /* Card container */ }
.card-header { /* Card header */ }
.card-body { /* Card body */ }
/* Badges */
.badge { /* Base badge */ }
.badge-info { /* Info badge variant */ }
/* Theme colors */
.text-theme-primary { /* Primary text color */ }
.bg-theme-primary { /* Primary background color */ }
.border-theme-primary { /* Primary border color */ }
.text-white { /* White text */ }CSS Custom Properties (Optional)
For enhanced theming, define these CSS variables in your app:
:root {
--color-primary: #1d4ed8;
--color-text: #111827;
--color-textSecondary: #6b7280;
--color-border: #e5e7eb;
--color-background: #f9fafb;
/* Button styling */
--button-height: 2.5rem;
--button-padding: 0.75rem 1rem;
--button-borderRadius: 0.375rem;
--button-fontSize: 0.875rem;
--button-fontWeight: 500;
--button-transition: all 150ms ease;
/* Input styling */
--input-height: 2.5rem;
--input-padding: 0.5rem 1rem;
--input-borderColor: #d3d3d6;
--input-borderRadius: 0.375rem;
--input-background: #ffffff;
}For JetSetGo Apps
If you're using this component in a JetSetGo app, simply import your standard.css before the component:
import './standard.css'; // Your app's design system
import '@your-username/react-icon-picker/styles.css';Usage
Basic Usage
import React, { useState } from 'react';
import { IconPicker } from '@your-username/react-icon-picker';
import '@your-username/react-icon-picker/styles.css';
function MyComponent() {
const [selectedIcon, setSelectedIcon] = useState<string>('');
const [isPickerOpen, setIsPickerOpen] = useState(false);
return (
<div>
{/* Your custom trigger button */}
<button
onClick={() => setIsPickerOpen(true)}
className="btn-secondary"
>
{selectedIcon ? `Selected: ${selectedIcon}` : 'Choose an icon'}
</button>
{/* Icon picker modal */}
<IconPicker
isOpen={isPickerOpen}
onClose={() => setIsPickerOpen(false)}
selectedIcon={selectedIcon}
onIconSelect={setSelectedIcon}
/>
</div>
);
}Advanced Usage with Icon Display
import React, { useState } from 'react';
import { IconPicker, getIconByName } from '@your-username/react-icon-picker';
import '@your-username/react-icon-picker/styles.css';
function MyComponent() {
const [selectedIcon, setSelectedIcon] = useState<string>('Heart');
const [isPickerOpen, setIsPickerOpen] = useState(false);
const iconData = selectedIcon ? getIconByName(selectedIcon) : null;
const IconComponent = iconData?.component;
return (
<div className="space-y-4">
{/* Custom trigger with icon preview */}
<button
onClick={() => setIsPickerOpen(true)}
className="btn-secondary flex items-center gap-3"
>
{IconComponent && (
<IconComponent size={20} className="text-theme-primary" />
)}
{selectedIcon || 'Choose an icon'}
</button>
{/* Icon picker modal */}
<IconPicker
isOpen={isPickerOpen}
onClose={() => setIsPickerOpen(false)}
selectedIcon={selectedIcon}
onIconSelect={setSelectedIcon}
/>
{/* Display selected icon */}
{IconComponent && (
<div className="card card-body">
<div className="flex items-center gap-3">
<IconComponent size={24} className="text-theme-primary" />
<span className="font-medium">{selectedIcon}</span>
</div>
</div>
)}
</div>
);
}Form Integration
import React, { useState } from 'react';
import { IconPicker, getIconByName } from '@your-username/react-icon-picker';
import '@your-username/react-icon-picker/styles.css';
function CreateItemForm() {
const [formData, setFormData] = useState({
name: '',
icon: '',
description: ''
});
const [isPickerOpen, setIsPickerOpen] = useState(false);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
console.log('Form data:', formData);
};
const iconData = formData.icon ? getIconByName(formData.icon) : null;
const IconComponent = iconData?.component;
return (
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="block text-sm font-medium mb-2">
Item Name
</label>
<input
type="text"
value={formData.name}
onChange={(e) => setFormData(prev => ({ ...prev, name: e.target.value }))}
className="input"
/>
</div>
<div>
<label className="block text-sm font-medium mb-2">
Icon
</label>
<button
type="button"
onClick={() => setIsPickerOpen(true)}
className="input flex items-center gap-2 cursor-pointer"
>
{IconComponent ? (
<>
<IconComponent size={16} className="text-theme-primary" />
<span>{formData.icon}</span>
</>
) : (
<span className="text-gray-500">Select an icon</span>
)}
</button>
<IconPicker
isOpen={isPickerOpen}
onClose={() => setIsPickerOpen(false)}
selectedIcon={formData.icon}
onIconSelect={(icon) => setFormData(prev => ({ ...prev, icon }))}
/>
</div>
<button
type="submit"
className="btn-primary"
>
Create Item
</button>
</form>
);
}API Reference
IconPicker Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| isOpen | boolean | - | Controls whether the modal is open |
| onClose | () => void | - | Callback when modal should close |
| selectedIcon | string | undefined | Currently selected icon name |
| onIconSelect | (iconName: string) => void | - | Callback when an icon is selected |
Utility Functions
getIconByName(name: string)
Returns the icon data for a given icon name.
import { getIconByName } from '@your-username/react-icon-picker';
const iconData = getIconByName('Heart');
if (iconData) {
const IconComponent = iconData.component;
// Use IconComponent in your JSX
}searchIcons(query: string)
Returns filtered icons based on search query.
import { searchIcons } from '@your-username/react-icon-picker';
const results = searchIcons('arrow');
// Returns all icons matching "arrow" in name, keywords, or categoryIcon Data Structure
interface IconData {
name: string;
component: React.ComponentType<{ size?: number; className?: string }>;
keywords: string[];
category: string;
}Available Categories
- Actions - Interactive elements (check, plus, edit, etc.)
- Navigation - Directional and movement icons
- Communication - Messaging and social icons
- Business - Professional and office icons
- Transport - Vehicles and travel icons
- Media - Audio, video, and entertainment icons
- Files - Document and file management icons
- Interface - UI elements and controls
- Security - Protection and privacy icons
- People - User and person icons
- Location - Maps and places icons
- Weather - Climate and conditions icons
- Health - Medical and wellness icons
- Social - Social media and interaction icons
- Technology - Devices and digital icons
- Lifestyle - Personal and daily life icons
- Design - Creative and artistic icons
- Office - Business and workplace icons
- Alerts - Warning and notification icons
Styling
The component uses a hybrid styling approach for maximum compatibility:
- Visual styling (colors, typography) inherits from your app's design system
- Layout styling uses isolated
icon-picker-*classes for reliable positioning
Design System Integration
The component automatically adapts to your app's:
- Primary colors via
.text-theme-primary,.bg-theme-primary - Button styles via
.btn-primary,.btn-secondary - Form styles via
.input,.card,.badge - Typography and spacing from CSS custom properties
Layout Customization
To customize layout without breaking functionality, override these classes:
/* Modal sizing */
.icon-picker-content {
max-width: 600px; /* Default: 480px */
max-height: 700px; /* Default: 560px */
}
/* Icon grid layout */
.icon-picker-grid {
grid-template-columns: repeat(6, 1fr); /* Default: 4-5 columns */
gap: 12px; /* Default: 8px */
}
/* Icon card sizing */
.icon-picker-item {
height: 64px; /* Default: 56px */
}CSS Classes Reference
Layout Classes (safe to customize):
.icon-picker-modal- Modal overlay positioning.icon-picker-content- Modal container sizing.icon-picker-grid- Icon grid layout.icon-picker-item- Icon button dimensions.icon-picker-header- Header padding/layout.icon-picker-body- Body scrolling/padding.icon-picker-footer- Footer layout
Visual Classes (inherit from your app):
- Uses
.btn-primary,.btn-secondaryfor buttons - Uses
.inputfor search field - Uses
.card*for modal styling - Uses
.badge*for category pills - Uses
.text-theme-primaryetc. for colors
TypeScript Support
The package includes full TypeScript definitions. All components and utilities are fully typed for the best development experience.
import type { IconPickerProps, IconData } from '@your-username/react-icon-picker';Browser Support
- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+
Architecture
CSS Isolation Strategy
This component uses a safe namespacing approach to prevent CSS conflicts:
/* Layout Control - Component-specific */
.icon-picker-modal { /* Fixed positioning */ }
.icon-picker-grid { /* Grid layout */ }
.icon-picker-item { /* Icon sizing */ }
/* Visual Styling - Inherits from your app */
.btn-secondary { /* Your button styles */ }
.text-theme-primary { /* Your brand colors */ }
.input { /* Your form styling */ }Benefits:
- Component layout is bulletproof against host app CSS
- Visual styling automatically matches your design system
- No CSS conflicts or style bleeding
- Works with any CSS framework (Bootstrap, Tailwind, etc.)
Performance
- Bundle size: ~24KB CSS + ~19KB JS (gzipped ~5KB each)
- Runtime performance: Optimized with React.memo and efficient filtering
- CSS efficiency: Minimal custom CSS, inherits from parent app
- Accessibility: Full keyboard navigation and screen reader support
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
License
MIT License - feel free to use in personal and commercial projects.
Publishing to NPM
To publish this package to NPM:
- Update package.json: Replace
@your-username/react-icon-pickerwith your actual npm username/organization - Build the library: Run
npm run build:lib - Login to NPM: Run
npm login - Publish: Run
npm publish
Publishing Steps
# 1. Update the package name in package.json
# 2. Build the library
npm run build:lib
# 3. Login to NPM (if not already logged in)
npm login
# 4. Publish to NPM
npm publish
# For scoped packages (recommended)
npm publish --access publicDemo
A live demo is available at: [Your Demo URL]
Built with ❤️ using React, TypeScript, and Tailwind CSS
