import * as IconPark from '@icon-park/react'; import { Input, List, Modal, Pagination } from 'antd'; import { useState } from 'react'; const allIcons = Object.keys(IconPark); // 动态构造 iconMap const iconMap: Record = {}; allIcons.forEach((iconName) => { // 排除不需要的属性(如默认导出等) if ( iconName !== 'default' && typeof IconPark[iconName as keyof typeof IconPark] === 'function' ) { const IconComponent = IconPark[ iconName as keyof typeof IconPark ] as React.ComponentType; iconMap[iconName] = ; } }); // 图标选项列表 const iconOptions = Object.keys(iconMap).map((key) => ({ label: ( {iconMap[key]} {key} ), value: key, })); interface IconSelectorProps { value?: string; onChange?: (value: string) => void; } const IconSelector: React.FC = ({ value, onChange }) => { const [open, setOpen] = useState(false); const [searchValue, setSearchValue] = useState(''); const [currentPage, setCurrentPage] = useState(1); const pageSize = 48; // 过滤图标 const filteredIcons = iconOptions.filter( (option) => option.value.toLowerCase().includes(searchValue.toLowerCase()) || option.value.toLowerCase().includes(searchValue.toLowerCase()), ); // 分页数据 const paginatedIcons = filteredIcons.slice( (currentPage - 1) * pageSize, currentPage * pageSize, ); const handleSelect = (iconName: string) => { onChange?.(iconName); setOpen(false); setCurrentPage(1); setSearchValue(''); }; const handleClear = () => { onChange?.(''); setOpen(false); }; return ( <>
setOpen(true)} style={{ border: '1px solid #d9d9d9', borderRadius: 6, padding: '4px 11px', cursor: 'pointer', minHeight: 32, display: 'flex', alignItems: 'center', }} > {value ? ( {iconMap[value as keyof typeof iconMap]} {value} ) : ( 请选择图标 )}
{ setOpen(false); setCurrentPage(1); setSearchValue(''); }} onOk={() => setOpen(false)} width={800} styles={{ body: { padding: 0 } }} okText="确定" cancelText="取消" >
{ setSearchValue(e.target.value); setCurrentPage(1); }} style={{ marginBottom: 16 }} /> {filteredIcons.length === 0 ? ( ) : ( <> ( handleSelect(item.value)} style={{ cursor: 'pointer', textAlign: 'center', border: value === item.value ? '1px solid #1890ff' : '1px solid transparent', borderRadius: 6, padding: 8, }} >
{iconMap[item.value as keyof typeof iconMap]}
{item.value}
)} /> )}
); }; export default IconSelector;