| import * as React from 'react'; | 
| import Icon, * as AntdIcons from '@ant-design/icons'; | 
| import { Radio, Input, Empty } from 'antd'; | 
| import type { RadioChangeEvent } from 'antd/es/radio/interface'; | 
| import debounce from 'lodash/debounce'; | 
| import Category from './Category'; | 
| import IconPicSearcher from './IconPicSearcher'; | 
| import { FilledIcon, OutlinedIcon, TwoToneIcon } from './themeIcons'; | 
| import type { CategoriesKeys } from './fields'; | 
| import { categories } from './fields'; | 
| // import { useIntl } from '@umijs/max'; | 
|   | 
| export enum ThemeType { | 
|   Filled = 'Filled', | 
|   Outlined = 'Outlined', | 
|   TwoTone = 'TwoTone', | 
| } | 
|   | 
| const allIcons: { [key: string]: any } = AntdIcons; | 
|   | 
| interface IconSelectorProps { | 
|   //intl: any; | 
|   onSelect: any; | 
| } | 
|   | 
| interface IconSelectorState { | 
|   theme: ThemeType; | 
|   searchKey: string; | 
| } | 
|   | 
| const IconSelector: React.FC<IconSelectorProps> = (props) => { | 
|   // const intl = useIntl(); | 
|   // const { messages } = intl; | 
|   const { onSelect } = props; | 
|   const [displayState, setDisplayState] = React.useState<IconSelectorState>({ | 
|     theme: ThemeType.Outlined, | 
|     searchKey: '', | 
|   }); | 
|   | 
|   const newIconNames: string[] = []; | 
|   | 
|   const handleSearchIcon = React.useCallback( | 
|     debounce((searchKey: string) => { | 
|       setDisplayState(prevState => ({ ...prevState, searchKey })); | 
|     }), | 
|     [], | 
|   ); | 
|   | 
|   const handleChangeTheme = React.useCallback((e: RadioChangeEvent) => { | 
|     setDisplayState(prevState => ({ ...prevState, theme: e.target.value as ThemeType })); | 
|   }, []); | 
|   | 
|   const renderCategories = React.useMemo<React.ReactNode | React.ReactNode[]>(() => { | 
|     const { searchKey = '', theme } = displayState; | 
|   | 
|     const categoriesResult = Object.keys(categories) | 
|       .map((key: CategoriesKeys) => { | 
|         let iconList = categories[key]; | 
|         if (searchKey) { | 
|           const matchKey = searchKey | 
|             // eslint-disable-next-line prefer-regex-literals | 
|             .replace(new RegExp(`^<([a-zA-Z]*)\\s/>$`, 'gi'), (_, name) => name) | 
|             .replace(/(Filled|Outlined|TwoTone)$/, '') | 
|             .toLowerCase(); | 
|           iconList = iconList.filter((iconName:string) => iconName.toLowerCase().includes(matchKey)); | 
|         } | 
|   | 
|         // CopyrightCircle is same as Copyright, don't show it | 
|         iconList = iconList.filter((icon:string) => icon !== 'CopyrightCircle'); | 
|   | 
|         return { | 
|           category: key, | 
|           icons: iconList.map((iconName:string) => iconName + theme).filter((iconName:string) => allIcons[iconName]), | 
|         }; | 
|       }) | 
|       .filter(({ icons }) => !!icons.length) | 
|       .map(({ category, icons }) => ( | 
|         <Category | 
|           key={category} | 
|           title={category as CategoriesKeys} | 
|           theme={theme} | 
|           icons={icons} | 
|           newIcons={newIconNames} | 
|           onSelect={(type, name) => { | 
|             if (onSelect) { | 
|               onSelect(name, allIcons[name]); | 
|             } | 
|           }} | 
|         /> | 
|       )); | 
|     return categoriesResult.length === 0 ? <Empty style={{ margin: '2em 0' }} /> : categoriesResult; | 
|   }, [displayState.searchKey, displayState.theme]); | 
|   return ( | 
|     <> | 
|       <div style={{ display: 'flex', justifyContent: 'space-between' }}> | 
|         <Radio.Group | 
|           value={displayState.theme} | 
|           onChange={handleChangeTheme} | 
|           size="large" | 
|           optionType="button" | 
|           buttonStyle="solid" | 
|           options={[ | 
|             { | 
|               label:  <Icon component={OutlinedIcon} />, | 
|               value: ThemeType.Outlined | 
|             }, | 
|             { | 
|               label: <Icon component={FilledIcon} />, | 
|               value: ThemeType.Filled | 
|             }, | 
|             { | 
|               label: <Icon component={TwoToneIcon} />, | 
|               value: ThemeType.TwoTone | 
|             }, | 
|           ]} | 
|         > | 
|           {/* <Radio.Button value={ThemeType.Outlined}> | 
|             <Icon component={OutlinedIcon} /> {messages['app.docs.components.icon.outlined']} | 
|           </Radio.Button> | 
|           <Radio.Button value={ThemeType.Filled}> | 
|             <Icon component={FilledIcon} /> {messages['app.docs.components.icon.filled']} | 
|           </Radio.Button> | 
|           <Radio.Button value={ThemeType.TwoTone}> | 
|             <Icon component={TwoToneIcon} /> {messages['app.docs.components.icon.two-tone']} | 
|           </Radio.Button> */} | 
|         </Radio.Group> | 
|         <Input.Search | 
|           // placeholder={messages['app.docs.components.icon.search.placeholder']} | 
|           style={{ margin: '0 10px', flex: 1 }} | 
|           allowClear | 
|           onChange={e => handleSearchIcon(e.currentTarget.value)} | 
|           size="large" | 
|           autoFocus | 
|           suffix={<IconPicSearcher />} | 
|         /> | 
|       </div> | 
|       {renderCategories} | 
|     </> | 
|   ); | 
| }; | 
|   | 
| export default IconSelector |