@hsu-react/ui 0.0.21 → 0.0.22

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.
@@ -1,6 +1,6 @@
1
1
  import { ButtonProps as AntdButtonProps } from "antd";
2
2
  import React from "react";
3
- import { ChakraButtonProps } from "./ChakraButton";
3
+ import type { ChakraButtonProps } from "./ChakraButton";
4
4
  export type { ChakraButtonProps };
5
5
  export interface ButtonProps extends AntdButtonProps {
6
6
  hasPermi?: string[];
@@ -1,19 +1,33 @@
1
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
1
  var _excluded = ["hasPermi", "hidden", "iconPosition", "className", "children", "title"];
2
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
3
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
4
+ 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; }
3
5
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
6
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
7
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
8
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
7
9
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
8
- function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
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 { Button as AntdButton } from "antd";
11
- import React from "react";
11
+ import React, { Suspense, lazy } from "react";
12
12
  import usePermissions from "../../hooks/usePermissions";
13
13
  import classNames from "classnames";
14
14
  import styles from "./index.module.scss";
15
- import ChakraButton from "./ChakraButton";
16
15
  import { jsx as _jsx } from "react/jsx-runtime";
16
+ /**
17
+ * The chakra family weighs about 560 KB and serves only the Button.Chakra variant, yet it
18
+ * lands in every consumer's initial bundle because it hangs off the base Button. Switched to
19
+ * on-demand loading: the type goes through `import type` (erased at compile time), and the
20
+ * chunk is only fetched at runtime once Button.Chakra is actually rendered.
21
+ */
22
+ var InternalChakraButton = /*#__PURE__*/lazy(function () {
23
+ return import("./ChakraButton");
24
+ });
25
+ var ChakraButton = function ChakraButton(props) {
26
+ return /*#__PURE__*/_jsx(Suspense, {
27
+ fallback: null,
28
+ children: /*#__PURE__*/_jsx(InternalChakraButton, _objectSpread({}, props))
29
+ });
30
+ };
17
31
  // forwardRef: when wrapped by overlay components like Tooltip / Popconfirm, the button DOM can be accessed directly,
18
32
  // preventing rc libraries from falling back to findDOMNode and triggering React deprecation warnings
19
33
  var InternalButton = /*#__PURE__*/React.forwardRef(function (props, ref) {
@@ -1,4 +1,6 @@
1
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2
4
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
3
5
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
4
6
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
@@ -14,28 +16,45 @@ import Icon from "../../Icon";
14
16
  import Input from "../../Input";
15
17
  import styles from "./index.module.scss";
16
18
  import classNames from "classnames";
17
- import antDesignIcons from "@iconify/json/json/ant-design.json";
18
- import elementPlusIcons from "@iconify/json/json/ep.json";
19
- import fontAwesome4Icons from "@iconify/json/json/fa.json";
20
- import fontAwesome5SolidIcons from "@iconify/json/json/fa-solid.json";
19
+
20
+ /**
21
+ * The four selectable icon sets are loaded on demand.
22
+ *
23
+ * Together these JSON files weigh about 1.9 MB, and a static import drags them into the
24
+ * initial bundle along with IconSelect:
25
+ *
26
+ * FormItem → FormSelect → IconSelect → @iconify/json/json/*.json
27
+ *
28
+ * Only pages like menu management ever actually open the icon picker, so the set metadata
29
+ * and the icon-name list are split apart: label / name stay static (the Tabs must render
30
+ * immediately), and the matching set is fetched for the current tab once the popover opens.
31
+ */
21
32
  import { jsx as _jsx } from "react/jsx-runtime";
22
33
  import { jsxs as _jsxs } from "react/jsx-runtime";
23
- var icons = [{
34
+ var ICON_SETS = [{
24
35
  label: "Ant Design",
25
36
  name: "ant-design",
26
- icons: Object.keys(antDesignIcons.icons)
37
+ load: function load() {
38
+ return import("@iconify/json/json/ant-design.json");
39
+ }
27
40
  }, {
28
41
  label: "Element Plus",
29
42
  name: "ep",
30
- icons: Object.keys(elementPlusIcons.icons)
43
+ load: function load() {
44
+ return import("@iconify/json/json/ep.json");
45
+ }
31
46
  }, {
32
47
  label: "Font Awesome 4",
33
48
  name: "fa",
34
- icons: Object.keys(fontAwesome4Icons.icons)
49
+ load: function load() {
50
+ return import("@iconify/json/json/fa.json");
51
+ }
35
52
  }, {
36
53
  label: "Font Awesome 5 Solid",
37
54
  name: "fa-solid",
38
- icons: Object.keys(fontAwesome5SolidIcons.icons)
55
+ load: function load() {
56
+ return import("@iconify/json/json/fa-solid.json");
57
+ }
39
58
  }];
40
59
  var IconSelect = function IconSelect(props) {
41
60
  var _props$value = props.value,
@@ -58,13 +77,22 @@ var IconSelect = function IconSelect(props) {
58
77
  _useState8 = _slicedToArray(_useState7, 2),
59
78
  activeIcon = _useState8[0],
60
79
  setActiveIcon = _useState8[1];
80
+ var _useState9 = useState(false),
81
+ _useState10 = _slicedToArray(_useState9, 2),
82
+ open = _useState10[0],
83
+ setOpen = _useState10[1];
84
+ /** Loaded icon-name lists, cached by set name */
85
+ var _useState11 = useState({}),
86
+ _useState12 = _slicedToArray(_useState11, 2),
87
+ iconNames = _useState12[0],
88
+ setIconNames = _useState12[1];
61
89
  useEffect(function () {
62
- setCurrentTab(icons[0].name);
90
+ setCurrentTab(ICON_SETS[0].name);
63
91
  }, []);
64
92
  useEffect(function () {
65
93
  if (value && value !== _value) {
66
94
  setValue(value);
67
- if (icons.find(function (item) {
95
+ if (ICON_SETS.find(function (item) {
68
96
  return item.name === value.split(":")[0];
69
97
  })) {
70
98
  setCurrentTab(value.split(":")[0]);
@@ -72,6 +100,28 @@ var IconSelect = function IconSelect(props) {
72
100
  }
73
101
  }
74
102
  }, [value, _value]);
103
+
104
+ // Only fetch the current tab's icon names once the popover is open, and only once per set
105
+ useEffect(function () {
106
+ if (!open || !currentTab || iconNames[currentTab]) return;
107
+ var target = ICON_SETS.find(function (item) {
108
+ return item.name === currentTab;
109
+ });
110
+ if (!target) return;
111
+ var alive = true;
112
+ target.load().then(function (module) {
113
+ var _default;
114
+ if (!alive) return;
115
+ var json = (_default = module.default) !== null && _default !== void 0 ? _default : module;
116
+ setIconNames(function (prev) {
117
+ var _json$icons;
118
+ return _objectSpread(_objectSpread({}, prev), {}, _defineProperty({}, currentTab, Object.keys((_json$icons = json.icons) !== null && _json$icons !== void 0 ? _json$icons : {})));
119
+ });
120
+ });
121
+ return function () {
122
+ alive = false;
123
+ };
124
+ }, [open, currentTab, iconNames]);
75
125
  var _onChange = function _onChange(value) {
76
126
  setValue(value);
77
127
  onChange === null || onChange === void 0 || onChange(value);
@@ -85,6 +135,8 @@ var IconSelect = function IconSelect(props) {
85
135
  placement: "bottom",
86
136
  trigger: "click",
87
137
  zIndex: 1000,
138
+ open: open,
139
+ onOpenChange: setOpen,
88
140
  content: /*#__PURE__*/_jsxs("div", {
89
141
  className: styles.popoverContent,
90
142
  children: [/*#__PURE__*/_jsx(Input, {
@@ -100,16 +152,16 @@ var IconSelect = function IconSelect(props) {
100
152
  onChange: function onChange(key) {
101
153
  setCurrentTab(key);
102
154
  },
103
- items: icons === null || icons === void 0 ? void 0 : icons.map(function (type) {
104
- var _type$icons;
155
+ items: ICON_SETS.map(function (type) {
156
+ var _iconNames$type$name;
105
157
  return {
106
158
  label: type.label,
107
159
  key: type.name,
108
160
  children: /*#__PURE__*/_jsx("div", {
109
161
  className: classNames(styles.typeIcon),
110
- children: (_type$icons = type.icons) === null || _type$icons === void 0 || (_type$icons = _type$icons.filter(function (i) {
162
+ children: ((_iconNames$type$name = iconNames[type.name]) !== null && _iconNames$type$name !== void 0 ? _iconNames$type$name : []).filter(function (i) {
111
163
  return i.includes(search);
112
- })) === null || _type$icons === void 0 ? void 0 : _type$icons.map(function (item) {
164
+ }).map(function (item) {
113
165
  return /*#__PURE__*/_jsx(Tooltip, {
114
166
  title: type.name + ":" + item,
115
167
  placement: "top",
@@ -1,6 +1,6 @@
1
1
  import { ButtonProps as AntdButtonProps } from "antd";
2
2
  import React from "react";
3
- import { ChakraButtonProps } from "./ChakraButton";
3
+ import type { ChakraButtonProps } from "./ChakraButton";
4
4
  export type { ChakraButtonProps };
5
5
  export interface ButtonProps extends AntdButtonProps {
6
6
  hasPermi?: string[];
@@ -5,13 +5,27 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _antd = require("antd");
8
- var _react = _interopRequireDefault(require("react"));
8
+ var _react = _interopRequireWildcard(require("react"));
9
9
  var _usePermissions = _interopRequireDefault(require("../../hooks/usePermissions"));
10
10
  var _classnames = _interopRequireDefault(require("classnames"));
11
11
  var _indexModule = _interopRequireDefault(require("./index.module.scss"));
12
- var _ChakraButton = _interopRequireDefault(require("./ChakraButton"));
13
12
  var _jsxRuntime = require("react/jsx-runtime");
14
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
15
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
16
+ /**
17
+ * The chakra family weighs about 560 KB and serves only the Button.Chakra variant, yet it
18
+ * lands in every consumer's initial bundle because it hangs off the base Button. Switched to
19
+ * on-demand loading: the type goes through `import type` (erased at compile time), and the
20
+ * chunk is only fetched at runtime once Button.Chakra is actually rendered.
21
+ */
22
+ const InternalChakraButton = /*#__PURE__*/(0, _react.lazy)(() => Promise.resolve().then(() => _interopRequireWildcard(require("./ChakraButton"))));
23
+ const ChakraButton = props => /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.Suspense, {
24
+ fallback: null,
25
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(InternalChakraButton, {
26
+ ...props
27
+ })
28
+ });
15
29
  // forwardRef: when wrapped by overlay components like Tooltip / Popconfirm, the button DOM can be accessed directly,
16
30
  // preventing rc libraries from falling back to findDOMNode and triggering React deprecation warnings
17
31
  const InternalButton = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
@@ -40,5 +54,5 @@ const InternalButton = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
40
54
  });
41
55
  });
42
56
  const Button = InternalButton;
43
- Button.Chakra = _ChakraButton.default;
57
+ Button.Chakra = ChakraButton;
44
58
  var _default = exports.default = Button;
@@ -10,30 +10,37 @@ var _Icon = _interopRequireDefault(require("../../Icon"));
10
10
  var _Input = _interopRequireDefault(require("../../Input"));
11
11
  var _indexModule = _interopRequireDefault(require("./index.module.scss"));
12
12
  var _classnames = _interopRequireDefault(require("classnames"));
13
- var _antDesign = _interopRequireDefault(require("@iconify/json/json/ant-design.json"));
14
- var _ep = _interopRequireDefault(require("@iconify/json/json/ep.json"));
15
- var _fa = _interopRequireDefault(require("@iconify/json/json/fa.json"));
16
- var _faSolid = _interopRequireDefault(require("@iconify/json/json/fa-solid.json"));
17
13
  var _jsxRuntime = require("react/jsx-runtime");
18
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
15
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
20
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
21
- const icons = [{
16
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } /**
17
+ * The four selectable icon sets are loaded on demand.
18
+ *
19
+ * Together these JSON files weigh about 1.9 MB, and a static import drags them into the
20
+ * initial bundle along with IconSelect:
21
+ *
22
+ * FormItem → FormSelect → IconSelect → @iconify/json/json/*.json
23
+ *
24
+ * Only pages like menu management ever actually open the icon picker, so the set metadata
25
+ * and the icon-name list are split apart: label / name stay static (the Tabs must render
26
+ * immediately), and the matching set is fetched for the current tab once the popover opens.
27
+ */
28
+ const ICON_SETS = [{
22
29
  label: "Ant Design",
23
30
  name: "ant-design",
24
- icons: Object.keys(_antDesign.default.icons)
31
+ load: () => Promise.resolve().then(() => _interopRequireWildcard(require("@iconify/json/json/ant-design.json")))
25
32
  }, {
26
33
  label: "Element Plus",
27
34
  name: "ep",
28
- icons: Object.keys(_ep.default.icons)
35
+ load: () => Promise.resolve().then(() => _interopRequireWildcard(require("@iconify/json/json/ep.json")))
29
36
  }, {
30
37
  label: "Font Awesome 4",
31
38
  name: "fa",
32
- icons: Object.keys(_fa.default.icons)
39
+ load: () => Promise.resolve().then(() => _interopRequireWildcard(require("@iconify/json/json/fa.json")))
33
40
  }, {
34
41
  label: "Font Awesome 5 Solid",
35
42
  name: "fa-solid",
36
- icons: Object.keys(_faSolid.default.icons)
43
+ load: () => Promise.resolve().then(() => _interopRequireWildcard(require("@iconify/json/json/fa-solid.json")))
37
44
  }];
38
45
  const IconSelect = props => {
39
46
  const {
@@ -45,18 +52,40 @@ const IconSelect = props => {
45
52
  const [search, setSearch] = (0, _react.useState)("");
46
53
  const [currentTab, setCurrentTab] = (0, _react.useState)("");
47
54
  const [activeIcon, setActiveIcon] = (0, _react.useState)("");
55
+ const [open, setOpen] = (0, _react.useState)(false);
56
+ /** Loaded icon-name lists, cached by set name */
57
+ const [iconNames, setIconNames] = (0, _react.useState)({});
48
58
  (0, _react.useEffect)(() => {
49
- setCurrentTab(icons[0].name);
59
+ setCurrentTab(ICON_SETS[0].name);
50
60
  }, []);
51
61
  (0, _react.useEffect)(() => {
52
62
  if (value && value !== _value) {
53
63
  setValue(value);
54
- if (icons.find(item => item.name === value.split(":")[0])) {
64
+ if (ICON_SETS.find(item => item.name === value.split(":")[0])) {
55
65
  setCurrentTab(value.split(":")[0]);
56
66
  setActiveIcon(value);
57
67
  }
58
68
  }
59
69
  }, [value, _value]);
70
+
71
+ // Only fetch the current tab's icon names once the popover is open, and only once per set
72
+ (0, _react.useEffect)(() => {
73
+ if (!open || !currentTab || iconNames[currentTab]) return;
74
+ const target = ICON_SETS.find(item => item.name === currentTab);
75
+ if (!target) return;
76
+ let alive = true;
77
+ target.load().then(module => {
78
+ if (!alive) return;
79
+ const json = module.default ?? module;
80
+ setIconNames(prev => ({
81
+ ...prev,
82
+ [currentTab]: Object.keys(json.icons ?? {})
83
+ }));
84
+ });
85
+ return () => {
86
+ alive = false;
87
+ };
88
+ }, [open, currentTab, iconNames]);
60
89
  const _onChange = value => {
61
90
  setValue(value);
62
91
  onChange?.(value);
@@ -70,6 +99,8 @@ const IconSelect = props => {
70
99
  placement: "bottom",
71
100
  trigger: "click",
72
101
  zIndex: 1000,
102
+ open: open,
103
+ onOpenChange: setOpen,
73
104
  content: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
74
105
  className: _indexModule.default.popoverContent,
75
106
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Input.default, {
@@ -85,12 +116,12 @@ const IconSelect = props => {
85
116
  onChange: key => {
86
117
  setCurrentTab(key);
87
118
  },
88
- items: icons?.map(type => ({
119
+ items: ICON_SETS.map(type => ({
89
120
  label: type.label,
90
121
  key: type.name,
91
122
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
92
123
  className: (0, _classnames.default)(_indexModule.default.typeIcon),
93
- children: type.icons?.filter(i => i.includes(search))?.map(item => {
124
+ children: (iconNames[type.name] ?? []).filter(i => i.includes(search)).map(item => {
94
125
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, {
95
126
  title: type.name + ":" + item,
96
127
  placement: "top",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hsu-react/ui",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
4
  "description": "一套基于 React + Ant Design 的中后台业务组件库",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,13 +1,27 @@
1
1
  import { Button as AntdButton, ButtonProps as AntdButtonProps } from "antd";
2
2
 
3
- import React from "react";
3
+ import React, { Suspense, lazy } from "react";
4
4
  import usePermissions from "../../hooks/usePermissions";
5
5
  import classNames from "classnames";
6
6
  import styles from "./index.module.scss";
7
- import ChakraButton, { ChakraButtonProps } from "./ChakraButton";
7
+ import type { ChakraButtonProps } from "./ChakraButton";
8
8
 
9
9
  export type { ChakraButtonProps };
10
10
 
11
+ /**
12
+ * The chakra family weighs about 560 KB and serves only the Button.Chakra variant, yet it
13
+ * lands in every consumer's initial bundle because it hangs off the base Button. Switched to
14
+ * on-demand loading: the type goes through `import type` (erased at compile time), and the
15
+ * chunk is only fetched at runtime once Button.Chakra is actually rendered.
16
+ */
17
+ const InternalChakraButton = lazy(() => import("./ChakraButton"));
18
+
19
+ const ChakraButton: React.FC<ChakraButtonProps> = (props) => (
20
+ <Suspense fallback={null}>
21
+ <InternalChakraButton {...props} />
22
+ </Suspense>
23
+ );
24
+
11
25
  export interface ButtonProps extends AntdButtonProps {
12
26
  hasPermi?: string[];
13
27
  hidden?: boolean;
@@ -6,35 +6,42 @@ import Input from "../../Input";
6
6
  import styles from "./index.module.scss";
7
7
  import classNames from "classnames";
8
8
 
9
- import antDesignIcons from "@iconify/json/json/ant-design.json";
10
- import elementPlusIcons from "@iconify/json/json/ep.json";
11
- import fontAwesome4Icons from "@iconify/json/json/fa.json";
12
- import fontAwesome5SolidIcons from "@iconify/json/json/fa-solid.json";
13
-
14
- const icons: Array<{
9
+ /**
10
+ * The four selectable icon sets are loaded on demand.
11
+ *
12
+ * Together these JSON files weigh about 1.9 MB, and a static import drags them into the
13
+ * initial bundle along with IconSelect:
14
+ *
15
+ * FormItem → FormSelect → IconSelect → @iconify/json/json/*.json
16
+ *
17
+ * Only pages like menu management ever actually open the icon picker, so the set metadata
18
+ * and the icon-name list are split apart: label / name stay static (the Tabs must render
19
+ * immediately), and the matching set is fetched for the current tab once the popover opens.
20
+ */
21
+ const ICON_SETS: Array<{
15
22
  label: string;
16
23
  name: string;
17
- icons: string[];
24
+ load: () => Promise<unknown>;
18
25
  }> = [
19
26
  {
20
27
  label: "Ant Design",
21
28
  name: "ant-design",
22
- icons: Object.keys(antDesignIcons.icons),
29
+ load: () => import("@iconify/json/json/ant-design.json"),
23
30
  },
24
31
  {
25
32
  label: "Element Plus",
26
33
  name: "ep",
27
- icons: Object.keys(elementPlusIcons.icons),
34
+ load: () => import("@iconify/json/json/ep.json"),
28
35
  },
29
36
  {
30
37
  label: "Font Awesome 4",
31
38
  name: "fa",
32
- icons: Object.keys(fontAwesome4Icons.icons),
39
+ load: () => import("@iconify/json/json/fa.json"),
33
40
  },
34
41
  {
35
42
  label: "Font Awesome 5 Solid",
36
43
  name: "fa-solid",
37
- icons: Object.keys(fontAwesome5SolidIcons.icons),
44
+ load: () => import("@iconify/json/json/fa-solid.json"),
38
45
  },
39
46
  ];
40
47
 
@@ -50,22 +57,51 @@ const IconSelect: React.FC<IconSelectProps> = (props) => {
50
57
  const [search, setSearch] = useState<string>("");
51
58
  const [currentTab, setCurrentTab] = useState<string>("");
52
59
  const [activeIcon, setActiveIcon] = useState<string>("");
60
+ const [open, setOpen] = useState<boolean>(false);
61
+ /** Loaded icon-name lists, cached by set name */
62
+ const [iconNames, setIconNames] = useState<Record<string, string[]>>({});
53
63
 
54
64
  useEffect(() => {
55
- setCurrentTab(icons[0].name);
65
+ setCurrentTab(ICON_SETS[0].name);
56
66
  }, []);
57
67
 
58
68
  useEffect(() => {
59
69
  if (value && value !== _value) {
60
70
  setValue(value);
61
71
 
62
- if (icons.find((item) => item.name === value.split(":")[0])) {
72
+ if (ICON_SETS.find((item) => item.name === value.split(":")[0])) {
63
73
  setCurrentTab(value.split(":")[0]);
64
74
  setActiveIcon(value);
65
75
  }
66
76
  }
67
77
  }, [value, _value]);
68
78
 
79
+ // Only fetch the current tab's icon names once the popover is open, and only once per set
80
+ useEffect(() => {
81
+ if (!open || !currentTab || iconNames[currentTab]) return;
82
+
83
+ const target = ICON_SETS.find((item) => item.name === currentTab);
84
+ if (!target) return;
85
+
86
+ let alive = true;
87
+ target.load().then((module) => {
88
+ if (!alive) return;
89
+
90
+ const json = ((module as { default?: unknown }).default ?? module) as {
91
+ icons: Record<string, unknown>;
92
+ };
93
+
94
+ setIconNames((prev) => ({
95
+ ...prev,
96
+ [currentTab]: Object.keys(json.icons ?? {}),
97
+ }));
98
+ });
99
+
100
+ return () => {
101
+ alive = false;
102
+ };
103
+ }, [open, currentTab, iconNames]);
104
+
69
105
  const _onChange = (value: string) => {
70
106
  setValue(value);
71
107
  onChange?.(value);
@@ -82,6 +118,8 @@ const IconSelect: React.FC<IconSelectProps> = (props) => {
82
118
  placement="bottom"
83
119
  trigger="click"
84
120
  zIndex={1000}
121
+ open={open}
122
+ onOpenChange={setOpen}
85
123
  content={
86
124
  <div className={styles.popoverContent}>
87
125
  <Input
@@ -96,14 +134,14 @@ const IconSelect: React.FC<IconSelectProps> = (props) => {
96
134
  onChange={(key) => {
97
135
  setCurrentTab(key);
98
136
  }}
99
- items={icons?.map((type) => ({
137
+ items={ICON_SETS.map((type) => ({
100
138
  label: type.label,
101
139
  key: type.name,
102
140
  children: (
103
141
  <div className={classNames(styles.typeIcon)}>
104
- {type.icons
105
- ?.filter((i) => i.includes(search))
106
- ?.map((item: string) => {
142
+ {(iconNames[type.name] ?? [])
143
+ .filter((i) => i.includes(search))
144
+ .map((item: string) => {
107
145
  return (
108
146
  <Tooltip
109
147
  key={item}