@blocklet/ui-react 2.10.12 → 2.10.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/Icon/index.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import "iconify-icon";
3
+ import { useState } from "react";
4
+ import { useAsyncEffect } from "ahooks";
3
5
  import { Avatar } from "@mui/material";
4
- import { Icon as IconifyIcon } from "@iconify/react";
5
- import { isUrl, isIconifyString } from "../utils.js";
6
+ import { Icon as IconifyIcon, loadIcon } from "@iconify/react";
7
+ import { isUrl } from "../utils.js";
6
8
  export default function Icon({
7
9
  icon,
8
10
  size,
@@ -13,6 +15,18 @@ export default function Icon({
13
15
  if (size) {
14
16
  _sx.push({ width: size, height: size });
15
17
  }
18
+ const [isIconify, setIsIconify] = useState(false);
19
+ const [loading, setLoading] = useState(true);
20
+ useAsyncEffect(async () => {
21
+ setLoading(true);
22
+ try {
23
+ await loadIcon(icon);
24
+ setIsIconify(true);
25
+ } catch {
26
+ setIsIconify(false);
27
+ }
28
+ setLoading(false);
29
+ }, [icon]);
16
30
  if (!rest.variant) {
17
31
  _sx.push({
18
32
  "&.MuiAvatar-root": {
@@ -31,8 +45,11 @@ export default function Icon({
31
45
  if (isUrl(icon)) {
32
46
  return /* @__PURE__ */ jsx(Avatar, { component: "span", ...rest, src: icon, sx: _sx });
33
47
  }
34
- if (isIconifyString(icon)) {
35
- const height = size ? 0.6 * size + 4 : 0;
48
+ const height = size ? 0.6 * size + 4 : 0;
49
+ if (loading) {
50
+ return /* @__PURE__ */ jsx(IconifyIcon, { icon: "codicon:blank", height: height || void 0 });
51
+ }
52
+ if (isIconify) {
36
53
  return /* @__PURE__ */ jsx(Avatar, { component: "span", ...rest, sx: _sx, children: /* @__PURE__ */ jsx(IconifyIcon, { icon, height: height || void 0 }) });
37
54
  }
38
55
  if (icon && typeof icon === "string") {
package/lib/utils.js CHANGED
@@ -45,6 +45,10 @@ export const isUrl = (str) => {
45
45
  return /^https?:\/\//.test(str);
46
46
  };
47
47
 
48
+ /**
49
+ * @description 检测是否是 Iconify 格式的字符串
50
+ * @deprecated
51
+ */
48
52
  export const isIconifyString = (str) => {
49
53
  return /^[\w-]+:[\w-]+$/.test(str);
50
54
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/ui-react",
3
- "version": "2.10.12",
3
+ "version": "2.10.13",
4
4
  "description": "Some useful front-end web components that can be used in Blocklets.",
5
5
  "keywords": [
6
6
  "react",
@@ -32,8 +32,8 @@
32
32
  "url": "https://github.com/ArcBlock/ux/issues"
33
33
  },
34
34
  "dependencies": {
35
- "@arcblock/bridge": "^2.10.12",
36
- "@arcblock/react-hooks": "^2.10.12",
35
+ "@arcblock/bridge": "^2.10.13",
36
+ "@arcblock/react-hooks": "^2.10.13",
37
37
  "@iconify-icons/logos": "^1.2.36",
38
38
  "@iconify-icons/material-symbols": "^1.2.58",
39
39
  "@iconify/react": "^4.1.1",
@@ -79,5 +79,5 @@
79
79
  "jest": "^28.1.3",
80
80
  "unbuild": "^2.0.0"
81
81
  },
82
- "gitHead": "c32ebbc1536d9374a99865ff463f0a300b6e5372"
82
+ "gitHead": "572b07b7e8fff82c6c16a9f7814867a5f6d17c03"
83
83
  }
@@ -1,9 +1,10 @@
1
1
  import 'iconify-icon';
2
-
2
+ import { useState } from 'react';
3
+ import { useAsyncEffect } from 'ahooks';
3
4
  import { Avatar } from '@mui/material';
4
5
  import type { AvatarProps, BoxProps } from '@mui/material';
5
- import { Icon as IconifyIcon } from '@iconify/react';
6
- import { isUrl, isIconifyString } from '../utils';
6
+ import { Icon as IconifyIcon, loadIcon } from '@iconify/react';
7
+ import { isUrl } from '../utils';
7
8
 
8
9
  /**
9
10
  * Icon 组件, 基于 mui Avatar 组件扩展对 iconify 的支持
@@ -23,6 +24,19 @@ export default function Icon({
23
24
  if (size) {
24
25
  _sx.push({ width: size, height: size });
25
26
  }
27
+ const [isIconify, setIsIconify] = useState(false);
28
+ // NOTICE: 需要设置默认为 true,代表在判断 icon 是否为 iconify 时,需要等待 icon 加载完成
29
+ const [loading, setLoading] = useState(true);
30
+ useAsyncEffect(async () => {
31
+ setLoading(true);
32
+ try {
33
+ await loadIcon(icon);
34
+ setIsIconify(true);
35
+ } catch {
36
+ setIsIconify(false);
37
+ }
38
+ setLoading(false);
39
+ }, [icon]);
26
40
  // 禁用默认的 circular variant 样式
27
41
  if (!rest.variant) {
28
42
  _sx.push({
@@ -42,9 +56,13 @@ export default function Icon({
42
56
  if (isUrl(icon)) {
43
57
  return <Avatar component="span" {...rest} src={icon} sx={_sx} />;
44
58
  }
45
- if (isIconifyString(icon)) {
46
- // y = 0.6 * x + 4
47
- const height = size ? 0.6 * size + 4 : 0;
59
+ // y = 0.6 * x + 4
60
+ const height = size ? 0.6 * size + 4 : 0;
61
+
62
+ if (loading) {
63
+ return <IconifyIcon icon="codicon:blank" height={height || undefined} />;
64
+ }
65
+ if (isIconify) {
48
66
  return (
49
67
  <Avatar component="span" {...rest} sx={_sx}>
50
68
  <IconifyIcon icon={icon} height={height || undefined} />
package/src/utils.js CHANGED
@@ -45,6 +45,10 @@ export const isUrl = (str) => {
45
45
  return /^https?:\/\//.test(str);
46
46
  };
47
47
 
48
+ /**
49
+ * @description 检测是否是 Iconify 格式的字符串
50
+ * @deprecated
51
+ */
48
52
  export const isIconifyString = (str) => {
49
53
  return /^[\w-]+:[\w-]+$/.test(str);
50
54
  };