foxit-component 0.0.1-alpha.9 → 0.0.2

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.
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @name Alert
3
+ */
4
+ import React from 'react';
5
+ import './alert.css';
6
+ interface AlertProps {
7
+ message: string | React.ReactNode;
8
+ showIcon?: boolean;
9
+ type?: 'success' | 'warning' | 'error' | 'gradient';
10
+ }
11
+ declare const Alert: React.FC<AlertProps>;
12
+ export { Alert };
@@ -0,0 +1,24 @@
1
+ import { __assign } from '../node_modules/tslib/tslib.es6.js';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { Icon } from '../Icon/index.js';
4
+
5
+ var Alert = function (_a) {
6
+ var message = _a.message, _b = _a.showIcon, showIcon = _b === void 0 ? true : _b, _c = _a.type, type = _c === void 0 ? 'success' : _c;
7
+ var getIconName = function (type) {
8
+ switch (type) {
9
+ case 'success':
10
+ return 'SuccessColoursOutlined';
11
+ case 'error':
12
+ return 'ErrorColoursOutlined';
13
+ case 'warning':
14
+ return 'WarningColoursOutlined';
15
+ case 'loading':
16
+ return 'LoadingOutlined';
17
+ default:
18
+ return 'WarningColoursOutlined';
19
+ }
20
+ };
21
+ return (jsxs("div", __assign({ className: "foxit-alert foxit-alert-".concat(type) }, { children: [showIcon && (jsx("div", __assign({ className: "foxit-alert-icon-container" }, { children: jsx(Icon, { name: getIconName(type), className: "foxit-alert-icon" }) }))), jsx("div", __assign({ className: "foxit-alert-message" }, { children: message }))] })));
22
+ };
23
+
24
+ export { Alert };
@@ -6,7 +6,7 @@ import { Icon } from '../Icon/index.js';
6
6
  var Button = function (_a) {
7
7
  var _b = _a.primary, primary = _b === void 0 ? false : _b, _c = _a.size, size = _c === void 0 ? 'large' : _c, _d = _a.children, children = _d === void 0 ? '' : _d, className = _a.className, style = _a.style, loading = _a.loading, props = __rest(_a, ["primary", "size", "children", "className", "style", "loading"]);
8
8
  var mode = primary ? 'foxit-button-primary' : 'foxit-button-secondary';
9
- return (jsxs("button", __assign({ type: "button", className: classNames('foxit-button', "foxit-button-".concat(size), mode, className), style: style }, props, { children: [loading && jsx(Icon, { name: "LoadingOutlined", className: "foxit-button-loading" }), children] })));
9
+ return (jsxs("button", __assign({ type: "button", className: classNames('foxit-button', "foxit-button-".concat(size), mode, className, loading && 'foxit-button-prevent-click'), style: style }, props, { children: [loading && jsx(Icon, { name: "LoadingOutlined", className: "foxit-button-loading" }), children] })));
10
10
  };
11
11
 
12
12
  export { Button };
@@ -0,0 +1,10 @@
1
+ import React, { ReactNode } from 'react';
2
+ import './drawer.css';
3
+ interface DrawerProps {
4
+ open?: boolean;
5
+ width?: number | string;
6
+ onClose?: () => void;
7
+ children?: ReactNode;
8
+ }
9
+ declare const Drawer: React.FC<DrawerProps>;
10
+ export { Drawer };
@@ -0,0 +1,14 @@
1
+ import { __assign } from '../node_modules/tslib/tslib.es6.js';
2
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
+ import classNames from 'classnames';
4
+
5
+ var Drawer = function (_a) {
6
+ var open = _a.open, _b = _a.width, width = _b === void 0 ? 375 : _b, onClose = _a.onClose, children = _a.children;
7
+ return (jsxs(Fragment, { children: [jsx("div", { className: classNames('foxit-drawer-mask', {
8
+ 'foxit-drawer-mask-open': open
9
+ }), onClick: onClose, style: { display: open ? 'block' : 'none' } }), jsx("div", __assign({ className: classNames('foxit-drawer', {
10
+ 'foxit-drawer-open': open
11
+ }), style: { width: width, right: open ? 0 : -width } }, { children: jsx("div", __assign({ className: "foxit-drawer-content" }, { children: children })) }))] }));
12
+ };
13
+
14
+ export { Drawer };
package/es/Form/Form.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import React, { ReactNode } from 'react';
2
2
  import { FormRefInstance } from './Form.types';
3
3
  import FormItem from './FormItem';
4
+ import { useFormWatch } from './useFormWatch';
4
5
  export type { FormRefInstance } from './Form.types';
5
6
  interface FormProps {
6
7
  children: ReactNode;
@@ -9,6 +10,6 @@ interface FormProps {
9
10
  [key: string]: unknown;
10
11
  };
11
12
  }
12
- export { FormItem };
13
+ export { FormItem, useFormWatch };
13
14
  declare const _default: React.ForwardRefExoticComponent<FormProps & React.RefAttributes<FormRefInstance>>;
14
15
  export default _default;
package/es/Form/Form.js CHANGED
@@ -21,13 +21,14 @@ var Form = function (_a, ref) {
21
21
  }
22
22
  }, [onFinish]);
23
23
  useImperativeHandle(ref, function () {
24
- var _a, _b, _c, _d, _e;
24
+ var _a, _b, _c, _d, _e, _f;
25
25
  return ({
26
26
  setFieldsValue: (_a = formRef.current) === null || _a === void 0 ? void 0 : _a.setFieldsValue,
27
27
  getFieldsValue: (_b = formRef.current) === null || _b === void 0 ? void 0 : _b.getFieldsValue,
28
28
  resetFields: (_c = formRef.current) === null || _c === void 0 ? void 0 : _c.resetFields,
29
29
  validateFields: (_d = formRef.current) === null || _d === void 0 ? void 0 : _d.validateFields,
30
- setFieldsStatus: (_e = formRef.current) === null || _e === void 0 ? void 0 : _e.setFieldsStatus
30
+ setFieldsStatus: (_e = formRef.current) === null || _e === void 0 ? void 0 : _e.setFieldsStatus,
31
+ subscribe: (_f = formRef.current) === null || _f === void 0 ? void 0 : _f.subscribe
31
32
  });
32
33
  });
33
34
  return (jsx(FormProvider, __assign({ initialValues: initialValues, ref: formRef }, { children: jsx("form", __assign({ onSubmit: handleSubmit }, { children: children })) })));
@@ -11,6 +11,12 @@ export interface ValidationRule {
11
11
  min?: number;
12
12
  max?: number;
13
13
  }
14
+ export interface FieldSubscriber {
15
+ fieldNames: string[];
16
+ callback: (values: {
17
+ [key: string]: unknown;
18
+ }) => void;
19
+ }
14
20
  export interface FormInstance {
15
21
  setFieldsValue: (values: {
16
22
  [key: string]: unknown;
@@ -29,6 +35,9 @@ export interface FormInstance {
29
35
  }[]) => void;
30
36
  registerField: (name: string, rules: ValidationRule[]) => void;
31
37
  unregisterField: (name: string) => void;
38
+ subscribe: (fieldNames: string[], callback: (values: {
39
+ [key: string]: unknown;
40
+ }) => void) => () => void;
32
41
  }
33
42
  export type FormRefInstance = Omit<FormInstance, 'registerField' | 'unregisterField'>;
34
43
  export interface FormContextProps {
@@ -2,7 +2,8 @@ import React, { ReactNode } from 'react';
2
2
  import './form.css';
3
3
  interface FormItemProps {
4
4
  name: string;
5
- label?: string;
5
+ label?: string | ReactNode;
6
+ extra?: string | ReactNode;
6
7
  rules?: {
7
8
  required?: boolean;
8
9
  message?: string;
@@ -1,11 +1,11 @@
1
1
  import { __assign } from '../node_modules/tslib/tslib.es6.js';
2
- import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
3
  import React, { useContext, useEffect, useCallback } from 'react';
4
4
  import { FormContext } from './FormContext.js';
5
5
 
6
6
  var FormItem = function (_a) {
7
7
  var _b, _c, _d;
8
- var name = _a.name, label = _a.label, _e = _a.rules, rules = _e === void 0 ? [] : _e, children = _a.children;
8
+ var name = _a.name, label = _a.label, extra = _a.extra, _e = _a.rules, rules = _e === void 0 ? [] : _e, children = _a.children;
9
9
  var _f = useContext(FormContext), form = _f.form, formFields = _f.formFields;
10
10
  // Register field when component mounts
11
11
  useEffect(function () {
@@ -23,7 +23,7 @@ var FormItem = function (_a) {
23
23
  var newValue = ((_b = e === null || e === void 0 ? void 0 : e.target) === null || _b === void 0 ? void 0 : _b.value) !== undefined ? e.target.value : e;
24
24
  form.setFieldsValue((_a = {}, _a[name] = newValue, _a));
25
25
  }, [form, name]);
26
- return (jsxs("div", __assign({ className: "foxit-form-item" }, { children: [label && jsx("label", { children: label }), jsx("span", __assign({ className: "".concat(error ? 'foxit-form-error-component' : warning ? 'foxit-form-warning-component' : '') }, { children: React.Children.map(children, function (child) {
26
+ return (jsxs("div", __assign({ className: "foxit-form-item", style: error || warning ? { marginBottom: 0 } : {} }, { children: [label && (jsxs("label", { children: [label, rules.some(function (rule) { return rule.required; }) && jsx("span", __assign({ className: "foxit-form-required" }, { children: "*" })), extra && jsx(Fragment, { children: extra })] })), jsx("span", __assign({ className: "".concat(error ? 'foxit-form-error-component' : warning ? 'foxit-form-warning-component' : '') }, { children: React.Children.map(children, function (child) {
27
27
  return React.cloneElement(child, {
28
28
  value: value,
29
29
  onChange: handleChange
@@ -8,6 +8,7 @@ var FormProvider = function (_a, ref) {
8
8
  var formFieldsRef = useRef({});
9
9
  var _c = useState({}), forceUpdate = _c[1]; // Used to force re-render when ref changes
10
10
  var formInstanceRef = useRef({});
11
+ var subscribersRef = useRef([]);
11
12
  // 初始值的设置
12
13
  useEffect(function () {
13
14
  if (Object.keys(initialValues).length > 0) {
@@ -23,6 +24,22 @@ var FormProvider = function (_a, ref) {
23
24
  forceUpdate({}); // Trigger re-render
24
25
  }
25
26
  }, [initialValues]);
27
+ // 订阅方法
28
+ var subscribe = useCallback(function (fieldNames, callback) {
29
+ var subscriber = { fieldNames: fieldNames, callback: callback };
30
+ subscribersRef.current.push(subscriber);
31
+ // 立即触发一次回调,提供当前值
32
+ var currentValues = fieldNames.reduce(function (acc, fieldName) {
33
+ var _a;
34
+ acc[fieldName] = (_a = formFieldsRef.current[fieldName]) === null || _a === void 0 ? void 0 : _a.value;
35
+ return acc;
36
+ }, {});
37
+ callback(currentValues);
38
+ // 返回取消订阅函数
39
+ return function () {
40
+ subscribersRef.current = subscribersRef.current.filter(function (s) { return s !== subscriber; });
41
+ };
42
+ }, []);
26
43
  // 注册字段
27
44
  var registerField = useCallback(function (name, rules) {
28
45
  formFieldsRef.current = __assign({}, formFieldsRef.current); // Create a new object
@@ -56,13 +73,17 @@ var FormProvider = function (_a, ref) {
56
73
  if (rule.type === 'string' && typeof value !== 'string') {
57
74
  return { type: 'error', message: rule.message || 'The input is not a string' };
58
75
  }
59
- if (rule.min !== undefined && typeof value === 'string' && value.length < rule.min) {
76
+ if (rule.min !== undefined &&
77
+ typeof value === 'string' &&
78
+ new Blob([value]).size < rule.min) {
60
79
  return {
61
80
  type: 'error',
62
81
  message: rule.message || "The input is less than ".concat(rule.min, " characters")
63
82
  };
64
83
  }
65
- if (rule.max !== undefined && typeof value === 'string' && value.length > rule.max) {
84
+ if (rule.max !== undefined &&
85
+ typeof value === 'string' &&
86
+ new Blob([value]).size > rule.max) {
66
87
  return {
67
88
  type: 'error',
68
89
  message: rule.message || "The input is more than ".concat(rule.max, " characters")
@@ -73,14 +94,19 @@ var FormProvider = function (_a, ref) {
73
94
  }, []);
74
95
  // 设置字段值
75
96
  var setFieldsValue = useCallback(function (values) {
76
- var _a;
97
+ var _a, _b;
98
+ var changedFields = [];
77
99
  formFieldsRef.current = __assign({}, formFieldsRef.current); // Create a new object
78
100
  for (var key in values) {
79
101
  if (Object.prototype.hasOwnProperty.call(values, key)) {
80
102
  var newValue = values[key];
103
+ var oldValue = (_a = formFieldsRef.current[key]) === null || _a === void 0 ? void 0 : _a.value;
104
+ if (JSON.stringify(oldValue) !== JSON.stringify(newValue)) {
105
+ changedFields.push(key);
106
+ }
81
107
  formFieldsRef.current[key] = __assign(__assign({}, formFieldsRef.current[key]), { value: newValue });
82
108
  // 验证字段
83
- var validation = validateField(key, newValue, ((_a = formFieldsRef.current[key]) === null || _a === void 0 ? void 0 : _a.rules) || []);
109
+ var validation = validateField(key, newValue, ((_b = formFieldsRef.current[key]) === null || _b === void 0 ? void 0 : _b.rules) || []);
84
110
  if (validation) {
85
111
  if (validation.type === 'error') {
86
112
  formFieldsRef.current[key] = __assign(__assign({}, formFieldsRef.current[key]), { error: validation.message, warning: undefined // Clear any previous warnings
@@ -96,6 +122,24 @@ var FormProvider = function (_a, ref) {
96
122
  }
97
123
  }
98
124
  }
125
+ // 通知订阅者
126
+ if (changedFields.length > 0 && subscribersRef.current.length > 0) {
127
+ subscribersRef.current.forEach(function (subscriber) {
128
+ // 检查是否有该订阅者关心的字段发生变化
129
+ var relevantFields = subscriber.fieldNames.filter(function (name) {
130
+ return changedFields.includes(name);
131
+ });
132
+ if (relevantFields.length > 0) {
133
+ // 提取订阅者关心的所有字段当前值
134
+ var watchValues = subscriber.fieldNames.reduce(function (acc, fieldName) {
135
+ var _a;
136
+ acc[fieldName] = (_a = formFieldsRef.current[fieldName]) === null || _a === void 0 ? void 0 : _a.value;
137
+ return acc;
138
+ }, {});
139
+ subscriber.callback(watchValues);
140
+ }
141
+ });
142
+ }
99
143
  forceUpdate({}); // Trigger re-render
100
144
  }, [validateField]);
101
145
  // 获取字段值
@@ -144,12 +188,12 @@ var FormProvider = function (_a, ref) {
144
188
  if (!field)
145
189
  continue; // Skip if field is not registered
146
190
  var validation = validateField(key, values[key], field.rules || []);
147
- if (validation) {
148
- if (validation.type === 'error') {
149
- errors[key] = validation.message;
191
+ if (validation || field.error || field.warning) {
192
+ if ((validation === null || validation === void 0 ? void 0 : validation.type) === 'error' || field.error) {
193
+ errors[key] = (validation === null || validation === void 0 ? void 0 : validation.message) || field.error || '';
150
194
  }
151
- else if (validation.type === 'warning') {
152
- validation.message;
195
+ else if ((validation === null || validation === void 0 ? void 0 : validation.type) === 'warning' || field.warning) {
196
+ (validation === null || validation === void 0 ? void 0 : validation.message) || field.warning || '';
153
197
  }
154
198
  }
155
199
  }
@@ -204,7 +248,8 @@ var FormProvider = function (_a, ref) {
204
248
  validateFields: validateFields,
205
249
  setFieldsStatus: setFieldsStatus,
206
250
  registerField: registerField,
207
- unregisterField: unregisterField
251
+ unregisterField: unregisterField,
252
+ subscribe: subscribe
208
253
  };
209
254
  // 暴露给外部的方法
210
255
  useImperativeHandle(ref, function () { return (__assign({}, formInstanceRef.current)); });
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import type { FormRefInstance } from './Form.types';
3
+ export declare function useFormWatch(formRef: React.RefObject<FormRefInstance>, callback: (values: Record<string, unknown>) => void, fieldNames: string[]): void;
@@ -0,0 +1,37 @@
1
+ import { useRef, useEffect } from 'react';
2
+
3
+ function useFormWatch(formRef, callback, fieldNames) {
4
+ var callbackRef = useRef(callback);
5
+ useEffect(function () {
6
+ callbackRef.current = callback;
7
+ }, [callback]);
8
+ // 处理表单字段监听
9
+ useEffect(function () {
10
+ // 如果表单引用不存在,设置轮询检查
11
+ if (!formRef.current) {
12
+ var checkInterval_1 = setInterval(function () {
13
+ if (formRef.current) {
14
+ clearInterval(checkInterval_1);
15
+ subscribeToFields();
16
+ }
17
+ }, 100);
18
+ // 清理轮询
19
+ return function () { return clearInterval(checkInterval_1); };
20
+ }
21
+ else {
22
+ // 表单引用存在,直接订阅
23
+ return subscribeToFields();
24
+ }
25
+ function subscribeToFields() {
26
+ var _a;
27
+ var unsubscribe = (_a = formRef.current) === null || _a === void 0 ? void 0 : _a.subscribe(fieldNames, function (newValues) {
28
+ callbackRef.current(newValues);
29
+ });
30
+ return function () {
31
+ unsubscribe === null || unsubscribe === void 0 ? void 0 : unsubscribe();
32
+ };
33
+ }
34
+ }, [formRef, fieldNames.join(',')]);
35
+ }
36
+
37
+ export { useFormWatch };
package/es/Menu/Menu.d.ts CHANGED
@@ -15,7 +15,9 @@ interface MenuProps {
15
15
  }) => void;
16
16
  defaultSelectedKeys?: string[];
17
17
  defaultOpenKeys?: string[];
18
+ selectedKeys?: string[];
18
19
  style?: React.CSSProperties;
20
+ inlineCollapsed?: boolean;
19
21
  }
20
22
  export declare const getItem: (label: ReactNode, key: Key, icon?: ReactNode, children?: MenuItem[], type?: 'group') => MenuItem;
21
23
  declare const Menu: React.FC<MenuProps>;
package/es/Menu/Menu.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { __assign, __spreadArray } from '../node_modules/tslib/tslib.es6.js';
2
- import { jsx, jsxs } from 'react/jsx-runtime';
3
- import { useState } from 'react';
2
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
+ import { useState, useRef, useEffect } from 'react';
4
4
  import { Icon } from '../Icon/index.js';
5
5
 
6
6
  var getItem = function (label, key, icon, children, type) {
@@ -13,23 +13,30 @@ var getItem = function (label, key, icon, children, type) {
13
13
  };
14
14
  };
15
15
  var Menu = function (_a) {
16
- var items = _a.items, onClick = _a.onClick, _b = _a.defaultSelectedKeys, defaultSelectedKeys = _b === void 0 ? [] : _b, _c = _a.defaultOpenKeys, defaultOpenKeys = _c === void 0 ? [] : _c, style = _a.style;
17
- var _d = useState(defaultOpenKeys), openKeys = _d[0], setOpenKeys = _d[1];
18
- var _e = useState(defaultSelectedKeys), selectedKeys = _e[0], setSelectedKeys = _e[1];
16
+ var items = _a.items, onClick = _a.onClick, _b = _a.defaultSelectedKeys, defaultSelectedKeys = _b === void 0 ? [] : _b, _c = _a.defaultOpenKeys, defaultOpenKeys = _c === void 0 ? [] : _c, controlledSelectedKeys = _a.selectedKeys, // 新增
17
+ style = _a.style, _d = _a.inlineCollapsed, inlineCollapsed = _d === void 0 ? false : _d;
18
+ var _e = useState(defaultOpenKeys), openKeys = _e[0], setOpenKeys = _e[1];
19
+ var _f = useState(defaultSelectedKeys), uncontrolledSelectedKeys = _f[0], setUncontrolledSelectedKeys = _f[1];
20
+ var selectedKeys = controlledSelectedKeys !== undefined ? controlledSelectedKeys : uncontrolledSelectedKeys;
21
+ var _g = useState(null), hoveredKey = _g[0], setHoveredKey = _g[1];
22
+ var _h = useState({ top: 0, left: 0 }), popupPosition = _h[0], setPopupPosition = _h[1];
23
+ var menuItemRefs = useRef({});
24
+ var popupRef = useRef(null);
19
25
  var handleMenuClick = function (e) {
20
26
  onClick === null || onClick === void 0 ? void 0 : onClick(e);
21
- setSelectedKeys([e.key]);
27
+ if (controlledSelectedKeys === undefined) {
28
+ setUncontrolledSelectedKeys([e.key]);
29
+ }
22
30
  };
23
- // const handleOpenChange = (keys: string[]) => {
24
- // setOpenKeys(keys);
25
- // };
26
31
  var isFirstLevel = function (item) {
27
32
  return items.some(function (i) { return i.key === item.key; });
28
33
  };
34
+ // 标准展开模式的菜单项渲染
29
35
  var renderMenuItem = function (item) {
30
36
  var isSelected = selectedKeys.includes(item.key.toString());
31
37
  return (jsx("div", __assign({ className: "foxit-menu-item ".concat(isSelected ? 'selected' : '') }, { children: jsxs("div", __assign({ className: "foxit-menu-item-content", onClick: function () { return handleMenuClick({ key: item.key.toString() }); } }, { children: [item.icon && jsx("span", __assign({ style: { marginRight: '8px' } }, { children: item.icon })), jsx("span", __assign({ className: isFirstLevel(item) ? 'foxit-menu-item-label' : '' }, { children: item.label }))] })) }), item.key));
32
38
  };
39
+ // 标准展开模式的子菜单渲染
33
40
  var renderSubMenu = function (item) {
34
41
  var isOpen = openKeys.includes(item.key.toString());
35
42
  return (jsxs("div", { children: [jsxs("div", __assign({ className: "foxit-menu-submenu-title", onClick: function () {
@@ -43,7 +50,118 @@ var Menu = function (_a) {
43
50
  return child.children ? renderSubMenu(child) : renderMenuItem(child);
44
51
  }) })))] }, item.key));
45
52
  };
46
- return (jsx("div", __assign({ className: "foxit-menu", style: __assign({}, style) }, { children: items.map(function (item) { return (item.children ? renderSubMenu(item) : renderMenuItem(item)); }) })));
53
+ // 收起模式的菜单项渲染
54
+ var renderMenuCollapsedItem = function (item) {
55
+ var isSelected = selectedKeys.includes(item.key.toString());
56
+ return (jsx("div", __assign({ ref: function (el) { return (menuItemRefs.current[item.key.toString()] = el); }, className: "foxit-menu-item foxit-menu-collapsed-item ".concat(isSelected ? 'selected' : ''), onMouseEnter: function () { return handleMouseEnter(item.key.toString()); }, onMouseLeave: handleMouseLeave }, { children: jsx("div", __assign({ className: "foxit-menu-item-content", onClick: function () { return handleMenuClick({ key: item.key.toString() }); } }, { children: item.icon && (jsx("span", __assign({ className: "foxit-menu-item-icon foxit-menu-item-icon-collapsed" }, { children: item.icon }))) })) }), item.key));
57
+ };
58
+ // 收起模式的子菜单渲染
59
+ var renderSubCollapsedMenu = function (item) {
60
+ var isSelected = selectedKeys.includes(item.key.toString());
61
+ return (jsx("div", __assign({ ref: function (el) { return (menuItemRefs.current[item.key.toString()] = el); }, className: "foxit-menu-submenu foxit-menu-collapsed-item ".concat(isSelected ? 'selected' : ''), onMouseEnter: function () { return handleMouseEnter(item.key.toString()); }, onMouseLeave: handleMouseLeave }, { children: jsx("div", __assign({ className: "foxit-menu-submenu-title" }, { children: item.icon && (jsx("span", __assign({ className: "foxit-menu-item-icon foxit-menu-item-icon-collapsed" }, { children: item.icon }))) })) }), item.key));
62
+ };
63
+ // 处理鼠标悬浮事件
64
+ var handleMouseEnter = function (key) {
65
+ setHoveredKey(key);
66
+ var itemRef = menuItemRefs.current[key];
67
+ if (itemRef) {
68
+ var rect = itemRef.getBoundingClientRect();
69
+ setPopupPosition({
70
+ top: rect.top,
71
+ left: rect.right + 5
72
+ });
73
+ }
74
+ };
75
+ // 处理鼠标离开事件
76
+ var handleMouseLeave = function () {
77
+ // 使用延时,允许鼠标移到弹出菜单上
78
+ setTimeout(function () {
79
+ if (!isMouseInPopup() && !isMouseOverAnyMenuItem()) {
80
+ setHoveredKey(null);
81
+ }
82
+ }, 50);
83
+ };
84
+ // 检查鼠标是否在弹出菜单中
85
+ var isMouseInPopup = function () {
86
+ return popupRef.current && popupRef.current.matches(':hover');
87
+ };
88
+ // 检查鼠标是否在任何菜单项上
89
+ var isMouseOverAnyMenuItem = function () {
90
+ return Object.values(menuItemRefs.current).some(function (ref) { return ref && ref.matches(':hover'); });
91
+ };
92
+ // 弹出子菜单渲染
93
+ var renderPopupMenu = function () {
94
+ if (!hoveredKey)
95
+ return null;
96
+ var item = findItemByKey(items, hoveredKey);
97
+ if (!(item === null || item === void 0 ? void 0 : item.children))
98
+ return null;
99
+ return (jsx("div", __assign({ ref: popupRef, className: "foxit-menu-popup", style: {
100
+ position: 'fixed',
101
+ top: "".concat(popupPosition.top, "px"),
102
+ left: "".concat(popupPosition.left, "px"),
103
+ zIndex: 1000
104
+ }, onMouseEnter: function () { return setHoveredKey(hoveredKey); }, onMouseLeave: function () { return setHoveredKey(null); } }, { children: jsxs("div", __assign({ className: "foxit-menu foxit-menu-popup-content" }, { children: [jsxs("div", __assign({ className: "foxit-menu-popup-title" }, { children: [jsx("span", __assign({ className: "foxit-menu-item-icon" }, { children: item.icon })), jsx("span", { children: item.label })] })), item.children.map(function (child) {
105
+ return child.children ? renderPopupSubMenu(child) : renderPopupMenuItem(child);
106
+ })] })) })));
107
+ };
108
+ // 弹出菜单中的普通菜单项渲染
109
+ var renderPopupMenuItem = function (item) {
110
+ var isSelected = selectedKeys.includes(item.key.toString());
111
+ return (jsx("div", __assign({ className: "foxit-menu-item ".concat(isSelected ? 'selected' : '') }, { children: jsxs("div", __assign({ className: "foxit-menu-item-content", onClick: function () {
112
+ handleMenuClick({ key: item.key.toString() });
113
+ setHoveredKey(null);
114
+ } }, { children: [item.icon && jsx("span", __assign({ className: "foxit-menu-item-icon" }, { children: item.icon })), jsx("span", { children: item.label })] })) }), item.key));
115
+ };
116
+ // 弹出菜单中的子菜单渲染
117
+ var renderPopupSubMenu = function (item) {
118
+ var isOpen = openKeys.includes(item.key.toString());
119
+ return (jsxs("div", { children: [jsxs("div", __assign({ className: "foxit-menu-submenu-title", onClick: function () {
120
+ if (isOpen) {
121
+ setOpenKeys(openKeys.filter(function (key) { return key !== item.key.toString(); }));
122
+ }
123
+ else {
124
+ setOpenKeys(__spreadArray(__spreadArray([], openKeys, true), [item.key.toString()], false));
125
+ }
126
+ } }, { children: [jsxs("div", __assign({ style: { display: 'flex', alignItems: 'center' } }, { children: [item.icon && jsx("span", __assign({ className: "foxit-menu-item-icon" }, { children: item.icon })), jsx("span", { children: item.label })] })), jsx("span", { children: jsx(Icon, { name: "DownOutlined", className: "foxit-menu-icon ".concat(isOpen ? '' : 'foxit-menu-rotated-icon') }) })] })), isOpen && item.children && (jsx("div", __assign({ className: "foxit-menu-submenu-items" }, { children: item.children.map(function (child) {
127
+ return child.children ? renderPopupSubMenu(child) : renderPopupMenuItem(child);
128
+ }) })))] }, item.key));
129
+ };
130
+ // 根据key查找菜单项
131
+ var findItemByKey = function (items, key) {
132
+ for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
133
+ var item = items_1[_i];
134
+ if (item.key.toString() === key) {
135
+ return item;
136
+ }
137
+ if (item.children) {
138
+ var found = findItemByKey(item.children, key);
139
+ if (found)
140
+ return found;
141
+ }
142
+ }
143
+ return undefined;
144
+ };
145
+ // 关闭副作用处理
146
+ useEffect(function () {
147
+ var handleClickOutside = function (event) {
148
+ if (hoveredKey &&
149
+ popupRef.current &&
150
+ !popupRef.current.contains(event.target) &&
151
+ !Object.values(menuItemRefs.current).some(function (ref) { return ref && ref.contains(event.target); })) {
152
+ setHoveredKey(null);
153
+ }
154
+ };
155
+ document.addEventListener('mousedown', handleClickOutside);
156
+ return function () {
157
+ document.removeEventListener('mousedown', handleClickOutside);
158
+ };
159
+ }, [hoveredKey]);
160
+ return (jsxs(Fragment, { children: [jsx("div", __assign({ className: "foxit-menu", style: __assign({}, style) }, { children: inlineCollapsed
161
+ ? items.map(function (item) {
162
+ return item.children ? renderSubCollapsedMenu(item) : renderMenuCollapsedItem(item);
163
+ })
164
+ : items.map(function (item) { return (item.children ? renderSubMenu(item) : renderMenuItem(item)); }) })), inlineCollapsed && hoveredKey && renderPopupMenu()] }));
47
165
  };
48
166
 
49
167
  export { Menu, getItem };
@@ -10,6 +10,8 @@ interface IModalProps {
10
10
  maskClosable?: boolean;
11
11
  children?: React.ReactNode;
12
12
  width?: string;
13
+ type?: 'success';
14
+ closable?: boolean;
13
15
  }
14
16
  interface ModalComponent extends FC<IModalProps> {
15
17
  confirm: (props: IModalProps & {
package/es/Modal/Modal.js CHANGED
@@ -2,80 +2,67 @@ import { __assign, __awaiter, __generator } from '../node_modules/tslib/tslib.es
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
3
  import { useState } from 'react';
4
4
  import { Icon } from '../Icon/index.js';
5
+ import classNames from 'classnames';
5
6
  import { createRoot } from 'react-dom/client';
6
7
  import { Modal as Modal$1 } from './ModalTemp.js';
7
8
  import { Button } from '../Button/Button.js';
8
9
 
9
10
  var ModalContent = function (_a) {
10
- var title = _a.title, onCancel = _a.onCancel, _b = _a.onCancelText, onCancelText = _b === void 0 ? undefined : _b, onOk = _a.onOk, _c = _a.onOkText, onOkText = _c === void 0 ? undefined : _c, children = _a.children, _d = _a.width, width = _d === void 0 ? '400px' : _d;
11
- var _e = useState(false), loading = _e[0], setLoading = _e[1];
12
- var _f = useState(false), cancelLoading = _f[0], setCancelLoading = _f[1];
11
+ var title = _a.title, onCancel = _a.onCancel, _b = _a.onCancelText, onCancelText = _b === void 0 ? undefined : _b, onOk = _a.onOk, _c = _a.onOkText, onOkText = _c === void 0 ? undefined : _c, children = _a.children, _d = _a.width, width = _d === void 0 ? '400px' : _d, type = _a.type, _e = _a.closable, closable = _e === void 0 ? true : _e;
12
+ var _f = useState(false), loading = _f[0], setLoading = _f[1];
13
+ var _g = useState(false), cancelLoading = _g[0], setCancelLoading = _g[1];
13
14
  var handleOk = function () { return __awaiter(void 0, void 0, void 0, function () {
14
- var result;
15
15
  return __generator(this, function (_a) {
16
16
  switch (_a.label) {
17
17
  case 0:
18
- if (!onOk) return [3 /*break*/, 6];
18
+ if (!onOk) return [3 /*break*/, 4];
19
19
  _a.label = 1;
20
20
  case 1:
21
- _a.trys.push([1, , 5, 6]);
22
- result = onOk();
23
- if (!(result instanceof Promise)) return [3 /*break*/, 3];
21
+ _a.trys.push([1, , 3, 4]);
24
22
  setLoading(true);
25
- return [4 /*yield*/, result];
23
+ return [4 /*yield*/, onOk()];
26
24
  case 2:
27
25
  _a.sent();
28
26
  return [3 /*break*/, 4];
29
27
  case 3:
30
- onOk();
31
- _a.label = 4;
32
- case 4: return [3 /*break*/, 6];
33
- case 5:
34
28
  setLoading(false);
35
29
  return [7 /*endfinally*/];
36
- case 6: return [2 /*return*/];
30
+ case 4: return [2 /*return*/];
37
31
  }
38
32
  });
39
33
  }); };
40
34
  var handleCancel = function () { return __awaiter(void 0, void 0, void 0, function () {
41
- var result;
42
35
  return __generator(this, function (_a) {
43
36
  switch (_a.label) {
44
37
  case 0:
45
- if (!onCancel) return [3 /*break*/, 6];
38
+ if (!onCancel) return [3 /*break*/, 4];
46
39
  _a.label = 1;
47
40
  case 1:
48
- _a.trys.push([1, , 5, 6]);
49
- result = onCancel();
50
- if (!(result instanceof Promise)) return [3 /*break*/, 3];
41
+ _a.trys.push([1, , 3, 4]);
51
42
  setCancelLoading(true);
52
- return [4 /*yield*/, result];
43
+ return [4 /*yield*/, onCancel()];
53
44
  case 2:
54
45
  _a.sent();
55
46
  return [3 /*break*/, 4];
56
47
  case 3:
57
- onCancel();
58
- _a.label = 4;
59
- case 4: return [3 /*break*/, 6];
60
- case 5:
61
48
  setCancelLoading(false);
62
49
  return [7 /*endfinally*/];
63
- case 6: return [2 /*return*/];
50
+ case 4: return [2 /*return*/];
64
51
  }
65
52
  });
66
53
  }); };
67
- return (jsxs("div", __assign({ className: "foxit-modal-content-container", style: {
68
- maxWidth: width,
54
+ return (jsxs("div", __assign({ className: classNames('foxit-modal-content-container', type === 'success' ? 'foxit-modal-success' : ''), style: {
55
+ maxWidth: "min(".concat(width, ", calc(100vw - 32px))"),
69
56
  width: width
70
- } }, { children: [jsxs("div", __assign({ className: "foxit-modal-head" }, { children: [jsx("div", __assign({ className: "foxit-modal-title" }, { children: title })), jsx("div", __assign({ onClick: onCancel, className: "foxit-modal-close-button" }, { children: jsx(Icon, { name: "CloseOutlined" }) }))] })), jsx("div", { children: children }), jsxs("div", __assign({ className: "foxit-modal-footer" }, { children: [onCancelText && (jsx(Button, __assign({ size: "medium", onClick: handleCancel, loading: cancelLoading }, { children: onCancelText }))), onOkText && (jsx(Button, __assign({ primary: true, size: "medium", onClick: handleOk, loading: loading }, { children: onOkText })))] }))] })));
57
+ } }, { children: [jsxs("div", __assign({ className: "foxit-modal-head" }, { children: [jsx("div", __assign({ className: "foxit-modal-title" }, { children: title })), closable && (jsx("div", __assign({ onClick: onCancel, className: type === 'success' ? 'foxit-modal-success-icon' : 'foxit-modal-close-button' }, { children: type === 'success' ? (jsx(Icon, { name: "FireWorkColoursOutlined" })) : (jsx(Icon, { name: "CloseOutlined" })) })))] })), jsx("div", __assign({ className: "foxit-modal-children" }, { children: children })), jsxs("div", __assign({ className: "foxit-modal-footer" }, { children: [onCancelText && (jsx(Button, __assign({ size: "medium", onClick: handleCancel, loading: cancelLoading }, { children: onCancelText }))), onOkText && (jsx(Button, __assign({ primary: true, size: "medium", onClick: handleOk, loading: loading }, { children: onOkText })))] }))] })));
71
58
  };
72
59
  var Modal = function (_a) {
73
- var title = _a.title, opened = _a.opened, onOk = _a.onOk, onOkText = _a.onOkText, onCancel = _a.onCancel, onCancelText = _a.onCancelText, maskClosable = _a.maskClosable, children = _a.children, width = _a.width;
74
- return (jsx(Modal$1, __assign({ opened: opened, onClose: onCancel || (function () { }), maskClosable: maskClosable, position: "top" }, { children: jsx(ModalContent, __assign({ title: title, width: width, onCancel: onCancel, onCancelText: onCancelText, onOk: onOk, onOkText: onOkText }, { children: children })) })));
60
+ var title = _a.title, opened = _a.opened, onOk = _a.onOk, onOkText = _a.onOkText, onCancel = _a.onCancel, onCancelText = _a.onCancelText, maskClosable = _a.maskClosable, children = _a.children, width = _a.width, type = _a.type, closable = _a.closable;
61
+ return (jsx(Modal$1, __assign({ opened: opened, onClose: onCancel || (function () { }), maskClosable: maskClosable, position: "top" }, { children: jsx(ModalContent, __assign({ title: title, width: width, onCancel: onCancel, onCancelText: onCancelText, onOk: onOk, onOkText: onOkText, type: type, closable: closable }, { children: children })) })));
75
62
  };
76
63
  // 语法糖的调用方式
77
64
  Modal.confirm = function (_a) {
78
- var title = _a.title, onOk = _a.onOk, onCancel = _a.onCancel, onOkText = _a.onOkText, onCancelText = _a.onCancelText, _b = _a.maskClosable, maskClosable = _b === void 0 ? true : _b, content = _a.content, width = _a.width;
65
+ var title = _a.title, onOk = _a.onOk, onCancel = _a.onCancel, onOkText = _a.onOkText, onCancelText = _a.onCancelText, _b = _a.maskClosable, maskClosable = _b === void 0 ? true : _b, content = _a.content, width = _a.width, closable = _a.closable;
79
66
  var modalRoot = document.createElement('div');
80
67
  document.body.appendChild(modalRoot);
81
68
  var root = createRoot(modalRoot);
@@ -117,7 +104,7 @@ Modal.confirm = function (_a) {
117
104
  : function () {
118
105
  onOk === null || onOk === void 0 ? void 0 : onOk();
119
106
  handleClose();
120
- }, onOkText: onOkText }, { children: content })) })));
107
+ }, onOkText: onOkText, closable: closable }, { children: content })) })));
121
108
  };
122
109
 
123
110
  export { Modal };