You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
import IconAll, { ALL_ICON_KEYS, IconType as ParkIconType, IIconAllProps } from '@icon-park/react/es/all'import React, { Fragment } from 'react'import * as AntIcons from '@ant-design/icons/es/icons'
import IconItem from './picker/IconRender.tsx'import { IconUnit } from './types.ts'import { createStyles } from '@/theme'
type Prefix = 'antd:' | 'park:';type IconType = `${Prefix}${string}`;
const useStyles = createStyles(({ css, cx }, props: any) => {
const keyframes = css`
@keyframes rotating { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } `
const container = css`
display: inline-flex; align-items: center; justify-content: center; `
const size = props.size ? css`
height: ${props.size}px; width: ${props.size}px; line-height: ${props.size}px; ` : ''
const isLoading = css`
animation: rotating 2s linear infinite; `
return { container: cx( container, size, props.className), isLoading: cx(keyframes, size, isLoading) }})
interface IconProps extends Pick<IconUnit, 'type'> { type: IconType | IconUnit['type'] isLoading?: boolean
[key: string]: any}
function isAntdOrParkIcon(value: string): value is IconType { return value.startsWith('antd:') || value.startsWith('park:')}
export function Icon(props: IconProps) {
const { styles, cx } = useStyles(props)
const { type, isLoading, ...other } = props if (type && isAntdOrParkIcon(type)) { const [ t, c ] = type.split(':') return <IconItem {...other as any} type={t} componentName={c}/> }
const AntIcon = AntIcons[type as keyof typeof AntIcons] if (AntIcon) { return <AntIcon {...other}/> }
//如果是http或https链接,直接返回图片
if (type && (type.startsWith('http') || type.startsWith('https') || type.startsWith('data:image'))) { // @ts-ignore 没有办法把所有的属性都传递给img
return <img src={type} alt="icon" width={16} height={16} {...other}/> }
if (ALL_ICON_KEYS.indexOf(type as ParkIconType) < 0) { return null }
return ( <Fragment> <IconAll type={type as IconType} className={cx(styles.container, { [styles.isLoading]: isLoading, })} theme="outline" size={other.size ?? 20} // fill="#868686"
strokeWidth={3} {...other}/> </Fragment> )}
// eslint-disable-next-line react-refresh/only-export-components
export const getIcon = (type: string, props?: Partial<IIconAllProps>) => {
if (React.isValidElement(type)) { return type } //判断是否为json格式
if (type && type.startsWith('{') && type.endsWith('}')) { try { const obj = JSON.parse(type) type = obj.type props = obj } catch (e) { /* empty */ } }
return <Icon type={type} {...props}/>}
export default Icon
|