{
if (displayMode === 'status') {
let iconItem;
if (icon) {
- if (typeof icon === 'string' && getIcon(icon)) {
- iconItem = ;
- } else {
- iconItem = generateIcon(cx, icon, 'Icon');
- }
+ iconItem = ;
}
if (!iconItem) {
iconItem = (
diff --git a/packages/amis-ui/src/components/TimelineItem.tsx b/packages/amis-ui/src/components/TimelineItem.tsx
index 218fcd4d6..5386b2a2b 100644
--- a/packages/amis-ui/src/components/TimelineItem.tsx
+++ b/packages/amis-ui/src/components/TimelineItem.tsx
@@ -1,9 +1,9 @@
import React, {ReactNode, useState} from 'react';
import {localeable, LocaleProps} from 'amis-core';
-import {themeable, ThemeProps, generateIcon} from 'amis-core';
+import {themeable, ThemeProps} from 'amis-core';
import {Icon} from './icons';
-import type {IconCheckedSchema} from 'amis-core';
+import type {IconCheckedSchema} from 'amis-ui';
export interface TimelineItemProps {
/**
@@ -118,11 +118,12 @@ export function TimelineItem(props: TimelineItem) {
{icon ? (
- {typeof icon === 'string' ? (
-
- ) : (
- generateIcon(cx, icon as any)
- )}
+
) : (
}
accordion
>
diff --git a/packages/amis-ui/src/components/formula/Picker.tsx b/packages/amis-ui/src/components/formula/Picker.tsx
index 7f488ae52..e88243272 100644
--- a/packages/amis-ui/src/components/formula/Picker.tsx
+++ b/packages/amis-ui/src/components/formula/Picker.tsx
@@ -13,7 +13,6 @@ import {
import {
autobind,
noop,
- generateIcon,
themeable,
localeable,
parse,
@@ -363,7 +362,7 @@ export class FormulaPicker extends React.Component<
...rest
} = this.props;
const {isOpened, value, editorValue, isError} = this.state;
- const iconElement = generateIcon(cx, icon, 'Icon');
+ const iconElement = ;
const mobileUI = useMobileUI && isMobile();
return (
diff --git a/packages/amis-ui/src/components/icons.tsx b/packages/amis-ui/src/components/icons.tsx
index 4383baa28..2d5e106d2 100644
--- a/packages/amis-ui/src/components/icons.tsx
+++ b/packages/amis-ui/src/components/icons.tsx
@@ -4,7 +4,7 @@
* @author fex
*/
import React, {useState, useEffect, useRef} from 'react';
-import cx from 'classnames';
+import cxClass from 'classnames';
import CloseIcon from '../icons/close.svg';
import CloseSmallIcon from '../icons/close-small.svg';
import StatusCloseIcon from '../icons/status-close.svg';
@@ -101,6 +101,7 @@ import NewEdit from '../icons/new-edit.svg';
import RotateLeft from '../icons/rotate-left.svg';
import RotateRight from '../icons/rotate-right.svg';
import ScaleOrigin from '../icons/scale-origin.svg';
+import {isObject} from 'lodash';
// 兼容原来的用法,后续不直接试用。
@@ -235,24 +236,56 @@ registerIcon('rotate-left', RotateLeft);
registerIcon('rotate-right', RotateRight);
registerIcon('scale-origin', ScaleOrigin);
+export interface IconCheckedSchema {
+ id: string;
+ name?: string;
+ svg?: string;
+}
+
+export interface IconCheckedSchemaNew {
+ type: 'icon';
+ icon: IconCheckedSchema;
+}
+
export function Icon({
icon,
className,
wrapClassName,
classPrefix = '',
+ classNameProp,
iconContent,
- ...rest
+ vendor,
+ cx: iconCx,
+ onClick = () => {}
}: {
icon: string;
iconContent?: string;
} & React.ComponentProps) {
- // jest 运行环境下,把指定的 icon 也输出到 snapshot 中。
- if (typeof jest !== 'undefined') {
- rest.icon = icon;
+ let cx = iconCx || cxClass;
+
+ if (!icon) {
+ return null;
}
- const [showCssIcon, setShowCssIcon] = useState(false);
+ // 直接的icon dom
+ if (React.isValidElement(icon)) {
+ return icon;
+ }
+ // 获取注册的icon
+ const Component = getIcon(icon);
+ if (Component) {
+ return (
+
+ );
+ }
+
+ // 从css变量中获取icon
function refFn(dom: any) {
if (dom) {
const style = getComputedStyle(dom);
@@ -266,41 +299,84 @@ export function Icon({
// 存储svg,不直接用innerHTML是防止渲染后变成的情况
dom.svgHTMLClone = svgHTML;
dom.style.display = '';
- setShowCssIcon(true);
}
- } else {
- // 当传入svg为空时,隐藏div,展示原icon
- dom.style.display = 'none';
- setShowCssIcon(false);
}
}
}
+ if (iconContent) {
+ return (
+
+ );
+ }
- const Component = getIcon(icon);
+ // 符合schema的icon
+ if (
+ isObject(icon) &&
+ (icon as IconCheckedSchemaNew).type === 'icon' &&
+ (icon as IconCheckedSchemaNew).icon
+ ) {
+ icon = (icon as IconCheckedSchemaNew).icon;
+ }
+
+ // icon是引用svg的情况
+ if (
+ isObject(icon) &&
+ typeof (icon as IconCheckedSchema).id === 'string' &&
+ (icon as IconCheckedSchema).id.startsWith('svg-')
+ ) {
+ return (
+
+ );
+ }
+
+ // icon是链接
const isURLIcon = typeof icon === 'string' && icon?.indexOf('.') !== -1;
- const isIconfont =
- typeof icon === 'string' &&
- (~icon?.indexOf('iconfont') || ~icon?.indexOf('fa'));
+ if (isURLIcon) {
+ return (
+
+ );
+ }
- return Component ? (
- <>
- {iconContent ? (
-
- ) : null}
- {!showCssIcon ? (
-
- ) : null}
- >
- ) : isURLIcon ? (
-
- ) : isIconfont ? (
-
- ) : (
- 没有 icon {icon}
- );
+ // icon是普通字符串
+ const isIconfont = typeof icon === 'string';
+
+ let iconPrefix = '';
+ if (vendor === 'iconfont') {
+ iconPrefix = `iconfont icon-${icon}`;
+ } else if (vendor === 'fa') {
+ //默认是fontawesome v4,兼容之前配置
+ iconPrefix = `${vendor} ${vendor}-${icon}`;
+ } else {
+ // 如果vendor为空,则不设置前缀,这样可以支持fontawesome v5、fontawesome v6或者其他框架
+ iconPrefix = icon;
+ }
+
+ if (isIconfont) {
+ return (
+
+ );
+ }
+
+ // 没有合适的图标
+ return 没有 icon {icon};
}
export {
diff --git a/packages/amis-ui/src/components/json-schema/Array.tsx b/packages/amis-ui/src/components/json-schema/Array.tsx
index c9fc130bd..baba3fa87 100644
--- a/packages/amis-ui/src/components/json-schema/Array.tsx
+++ b/packages/amis-ui/src/components/json-schema/Array.tsx
@@ -150,7 +150,7 @@ export function InputJSONSchemaArray(props: InputJSONSchemaItemProps) {
})}
onClick={toggleCollapsed}
>
-
+