import React, { useState, useEffect, Component } from 'react'; // setter使用@alifd/next,和编辑器保持一致 import { Input, Icon as NextIcon, Radio, Balloon, Search } from '@alifd/next'; import { get } from '../../_utils/utils'; import './style.less'; type IconGroup = 'outlined' | 'filled' | 'two-tone'; const IconGroupNameMap: Record = { outlined: '线框风格', filled: '实底风格', 'two-tone': '双色风格', }; function getAntdIconList() { const iframe = document.querySelector( 'iframe.lc-simulator-content-frame', ); const icons: Record = {}; // document.querySelectorAll('svg[style="position: absolute; width: 0px; height: 0px; overflow: hidden;"][aria-hidden="true"]') const antdIcons = get(iframe, 'contentWindow.icons', {}) as Record< string, any >; return Object.keys(antdIcons) .map(key => { const item = (antdIcons as any)[key]; if (typeof item !== 'object') { return null; } const name = item?.displayName ?? item?.render?.displayName ?? key; let group: IconGroup = 'outlined'; const lowercaseName = name.toLowerCase(); if (/outlined$/.test(lowercaseName)) { group = 'outlined'; } else if (/filled$/.test(lowercaseName)) { group = 'filled'; } else if (/twotone$/.test(lowercaseName)) { group = 'two-tone'; } else { return null; } return { name, group, icon: item, }; }) .filter(Boolean); } function getIconList() { const antdIconList = getAntdIconList(); return [...antdIconList]; } const Icon = (props: any) => { const { type, icons = {}, ...rest } = props; const Comp = icons[type]; if (!Comp) return null; return ; }; interface AntdIconSetterProps { value: string; type: string; defaultValue: string; placeholder: string; hasClear: boolean; onChange: (icon: string | object) => undefined; icons: string[]; } const AntdIconSetter = (props: AntdIconSetterProps) => { const [search, setSearch] = useState(''); const [icons, setIcons] = useState>({}); const [groups, setGroups] = useState<{ group: IconGroup; list: any[] }[]>([]); const [selectedGroup, setSelectedGroup] = useState('outlined'); const [firstLoad, setFirstLoad] = useState(true); const [list, setList] = useState([]); const { value, defaultValue, type, onChange, placeholder, hasClear } = props; const _value = typeof value === 'object' ? (value as any)?.props?.type : value; if (firstLoad && defaultValue && typeof value === 'undefined') { onChange(defaultValue); setFirstLoad(false); } const handleChange = (icon: string) => { if (type === 'string') { onChange(icon); } else if (type === 'node') { onChange({ componentName: 'Icon', props: { type: icon, }, }); } }; useEffect(() => { const iconList = getIconList(); const groups: { group: IconGroup; list: any[] }[] = []; const icons: any = {}; iconList.forEach(item => { const { group, name, icon } = item!; if (groups.every(item => item.group !== group)) { groups.push({ group: group as IconGroup, list: [] }); } const target = groups.find(item => item.group === group)!; target.list.push(item); icons[item!.name] = item?.icon; }); setIcons(icons); setGroups(groups); setSelectedGroup(groups[0]?.group); }, []); useEffect(() => { const currentGroup = groups.find(item => item.group === selectedGroup); setList( (currentGroup?.list ?? []).filter(item => { return search ? item.name.toLowerCase().indexOf(search.toLowerCase()) > -1 : true; }), ); }, [selectedGroup, search, groups]); const currentIcon = ( ); const clearIcon = hasClear && ( { e.preventDefault(); e.stopPropagation(); handleChange(''); }} /> ); const triggerNode = (
); return (
setSelectedGroup(value as any)} > {groups.map(item => ( {IconGroupNameMap[item.group]} ))}
    {list.map(item => (
  • handleChange(item.name)} >
    {item.name}
  • ))}
); }; AntdIconSetter.defaultProps = { value: undefined, type: 'string', defaultValue: '', hasClear: false, placeholder: '请点击选择 Icon', onChange: () => undefined, }; // 因为下面这个问题,setter必须使用class组件 // http://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/issues/109046 export default class extends Component { render() { return ; } }