@hsu-react/ui 2.4.3 → 2.4.4

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.
@@ -6,5 +6,11 @@ interface IconProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpa
6
6
  onRef?: (ref?: React.RefObject<HTMLDivElement>) => void;
7
7
  fontSize?: number | string;
8
8
  }
9
- declare const Icon: React.FC<IconProps>;
9
+ /**
10
+ * `forwardRef` 不是可选的:`Tooltip` / `Dropdown` / `Popover` 都要往触发元素上挂 ref
11
+ * 才能定位浮层。作为普通函数组件时,把 Icon 直接塞进它们里面会让 React 报
12
+ * “Function components cannot be given refs”,浮层的定位也失去了锚点。
13
+ * 图标是这几个组件最常见的触发元素,所以这个坑几乎人人会踩。
14
+ */
15
+ declare const Icon: React.ForwardRefExoticComponent<Omit<IconProps, "ref"> & React.RefAttributes<HTMLSpanElement>>;
10
16
  export default Icon;
@@ -9,7 +9,7 @@ function _objectWithoutProperties(source, excluded) { if (source == null) return
9
9
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
10
10
  import { Icon as Iconify } from "@iconify/react";
11
11
  import * as AntdIcons from "@ant-design/icons";
12
- import React, { useEffect, useRef } from "react";
12
+ import React, { useCallback, useEffect, useRef } from "react";
13
13
  import classNames from "classnames";
14
14
  import styles from "./index.module.scss";
15
15
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -19,7 +19,13 @@ var getAntdIcon = function getAntdIcon(icon) {
19
19
  if (!/(?:Outlined|Filled|TwoTone)$/.test(icon)) return undefined;
20
20
  return AntdIcons[icon];
21
21
  };
22
- var Icon = function Icon(props) {
22
+ /**
23
+ * `forwardRef` 不是可选的:`Tooltip` / `Dropdown` / `Popover` 都要往触发元素上挂 ref
24
+ * 才能定位浮层。作为普通函数组件时,把 Icon 直接塞进它们里面会让 React 报
25
+ * “Function components cannot be given refs”,浮层的定位也失去了锚点。
26
+ * 图标是这几个组件最常见的触发元素,所以这个坑几乎人人会踩。
27
+ */
28
+ var Icon = /*#__PURE__*/React.forwardRef(function (props, forwardedRef) {
23
29
  var iconProps = props.iconProps,
24
30
  icon = props.icon,
25
31
  className = props.className,
@@ -29,6 +35,17 @@ var Icon = function Icon(props) {
29
35
  fontSize = props.fontSize,
30
36
  iconConfig = _objectWithoutProperties(props, _excluded);
31
37
  var ref = useRef(null);
38
+
39
+ // 内外两个 ref 都要喂:内部这个是 `onRef` 回调的载体(老接口,不能动),
40
+ // 外部那个是浮层组件用来定位的
41
+ var setRef = useCallback(function (node) {
42
+ ref.current = node;
43
+ if (typeof forwardedRef === "function") {
44
+ forwardedRef(node);
45
+ } else if (forwardedRef) {
46
+ forwardedRef.current = node;
47
+ }
48
+ }, [forwardedRef]);
32
49
  useEffect(function () {
33
50
  onRef === null || onRef === void 0 || onRef(ref);
34
51
  }, [onRef, ref]);
@@ -43,7 +60,7 @@ var Icon = function Icon(props) {
43
60
  return /*#__PURE__*/_jsx(AntdNamedIcon, _objectSpread(_objectSpread({}, iconConfig), {}, {
44
61
  className: classNames([styles.icon, className]),
45
62
  style: mergedStyle,
46
- ref: ref
63
+ ref: setRef
47
64
  }));
48
65
  }
49
66
 
@@ -51,7 +68,7 @@ var Icon = function Icon(props) {
51
68
  // the antd Icon's svg (whose viewBox would scale the inner svg down so much the icon becomes invisible).
52
69
  return /*#__PURE__*/_jsx("span", _objectSpread(_objectSpread({}, iconConfig), {}, {
53
70
  role: "img",
54
- ref: ref,
71
+ ref: setRef,
55
72
  className: classNames(["anticon", styles.icon, className]),
56
73
  style: mergedStyle,
57
74
  children: /*#__PURE__*/_jsx(Iconify, _objectSpread(_objectSpread({}, iconProps), {}, {
@@ -60,5 +77,6 @@ var Icon = function Icon(props) {
60
77
  height: "1em"
61
78
  }))
62
79
  }));
63
- };
80
+ });
81
+ Icon.displayName = "Icon";
64
82
  export default Icon;
@@ -6,5 +6,11 @@ interface IconProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpa
6
6
  onRef?: (ref?: React.RefObject<HTMLDivElement>) => void;
7
7
  fontSize?: number | string;
8
8
  }
9
- declare const Icon: React.FC<IconProps>;
9
+ /**
10
+ * `forwardRef` 不是可选的:`Tooltip` / `Dropdown` / `Popover` 都要往触发元素上挂 ref
11
+ * 才能定位浮层。作为普通函数组件时,把 Icon 直接塞进它们里面会让 React 报
12
+ * “Function components cannot be given refs”,浮层的定位也失去了锚点。
13
+ * 图标是这几个组件最常见的触发元素,所以这个坑几乎人人会踩。
14
+ */
15
+ declare const Icon: React.ForwardRefExoticComponent<Omit<IconProps, "ref"> & React.RefAttributes<HTMLSpanElement>>;
10
16
  export default Icon;
@@ -19,7 +19,13 @@ const getAntdIcon = icon => {
19
19
  if (!/(?:Outlined|Filled|TwoTone)$/.test(icon)) return undefined;
20
20
  return AntdIcons[icon];
21
21
  };
22
- const Icon = props => {
22
+ /**
23
+ * `forwardRef` 不是可选的:`Tooltip` / `Dropdown` / `Popover` 都要往触发元素上挂 ref
24
+ * 才能定位浮层。作为普通函数组件时,把 Icon 直接塞进它们里面会让 React 报
25
+ * “Function components cannot be given refs”,浮层的定位也失去了锚点。
26
+ * 图标是这几个组件最常见的触发元素,所以这个坑几乎人人会踩。
27
+ */
28
+ const Icon = /*#__PURE__*/_react2.default.forwardRef((props, forwardedRef) => {
23
29
  const {
24
30
  iconProps,
25
31
  icon,
@@ -31,6 +37,17 @@ const Icon = props => {
31
37
  ...iconConfig
32
38
  } = props;
33
39
  const ref = (0, _react2.useRef)(null);
40
+
41
+ // 内外两个 ref 都要喂:内部这个是 `onRef` 回调的载体(老接口,不能动),
42
+ // 外部那个是浮层组件用来定位的
43
+ const setRef = (0, _react2.useCallback)(node => {
44
+ ref.current = node;
45
+ if (typeof forwardedRef === "function") {
46
+ forwardedRef(node);
47
+ } else if (forwardedRef) {
48
+ forwardedRef.current = node;
49
+ }
50
+ }, [forwardedRef]);
34
51
  (0, _react2.useEffect)(() => {
35
52
  onRef?.(ref);
36
53
  }, [onRef, ref]);
@@ -47,7 +64,7 @@ const Icon = props => {
47
64
  ...iconConfig,
48
65
  className: (0, _classnames.default)([_indexModule.default.icon, className]),
49
66
  style: mergedStyle,
50
- ref: ref
67
+ ref: setRef
51
68
  });
52
69
  }
53
70
 
@@ -56,7 +73,7 @@ const Icon = props => {
56
73
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
57
74
  ...iconConfig,
58
75
  role: "img",
59
- ref: ref,
76
+ ref: setRef,
60
77
  className: (0, _classnames.default)(["anticon", _indexModule.default.icon, className]),
61
78
  style: mergedStyle,
62
79
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.Icon, {
@@ -66,5 +83,6 @@ const Icon = props => {
66
83
  height: "1em"
67
84
  })
68
85
  });
69
- };
86
+ });
87
+ Icon.displayName = "Icon";
70
88
  var _default = exports.default = Icon;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hsu-react/ui",
3
- "version": "2.4.3",
3
+ "version": "2.4.4",
4
4
  "description": "一套基于 React + Ant Design 的中后台业务组件库",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -5,7 +5,7 @@ import {
5
5
  } from "@iconify/react";
6
6
 
7
7
  import * as AntdIcons from "@ant-design/icons";
8
- import React, { useEffect, useRef } from "react";
8
+ import React, { useCallback, useEffect, useRef } from "react";
9
9
  import classNames from "classnames";
10
10
  import styles from "./index.module.scss";
11
11
 
@@ -38,7 +38,13 @@ interface IconProps
38
38
  fontSize?: number | string;
39
39
  }
40
40
 
41
- const Icon: React.FC<IconProps> = (props) => {
41
+ /**
42
+ * `forwardRef` 不是可选的:`Tooltip` / `Dropdown` / `Popover` 都要往触发元素上挂 ref
43
+ * 才能定位浮层。作为普通函数组件时,把 Icon 直接塞进它们里面会让 React 报
44
+ * “Function components cannot be given refs”,浮层的定位也失去了锚点。
45
+ * 图标是这几个组件最常见的触发元素,所以这个坑几乎人人会踩。
46
+ */
47
+ const Icon = React.forwardRef<HTMLSpanElement, IconProps>((props, forwardedRef) => {
42
48
  const {
43
49
  iconProps,
44
50
  icon,
@@ -51,6 +57,22 @@ const Icon: React.FC<IconProps> = (props) => {
51
57
  } = props;
52
58
  const ref = useRef<HTMLDivElement>(null);
53
59
 
60
+ // 内外两个 ref 都要喂:内部这个是 `onRef` 回调的载体(老接口,不能动),
61
+ // 外部那个是浮层组件用来定位的
62
+ const setRef = useCallback(
63
+ (node: HTMLSpanElement | null) => {
64
+ (ref as React.MutableRefObject<HTMLDivElement | null>).current =
65
+ node as unknown as HTMLDivElement | null;
66
+
67
+ if (typeof forwardedRef === "function") {
68
+ forwardedRef(node);
69
+ } else if (forwardedRef) {
70
+ forwardedRef.current = node;
71
+ }
72
+ },
73
+ [forwardedRef]
74
+ );
75
+
54
76
  useEffect(() => {
55
77
  onRef?.(ref);
56
78
  }, [onRef, ref]);
@@ -69,7 +91,7 @@ const Icon: React.FC<IconProps> = (props) => {
69
91
  {...iconConfig}
70
92
  className={classNames([styles.icon, className])}
71
93
  style={mergedStyle}
72
- ref={ref as unknown as React.Ref<HTMLSpanElement>}
94
+ ref={setRef}
73
95
  />
74
96
  );
75
97
  }
@@ -80,13 +102,15 @@ const Icon: React.FC<IconProps> = (props) => {
80
102
  <span
81
103
  {...iconConfig}
82
104
  role="img"
83
- ref={ref as unknown as React.Ref<HTMLSpanElement>}
105
+ ref={setRef}
84
106
  className={classNames(["anticon", styles.icon, className])}
85
107
  style={mergedStyle}
86
108
  >
87
109
  <Iconify {...iconProps} icon={icon} width="1em" height="1em" />
88
110
  </span>
89
111
  );
90
- };
112
+ });
113
+
114
+ Icon.displayName = "Icon";
91
115
 
92
116
  export default Icon;