foxit-component 0.0.1-alpha.4 → 0.0.1-alpha.40

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.
Files changed (65) hide show
  1. package/es/Alert/Alert.d.ts +12 -0
  2. package/es/Alert/Alert.js +24 -0
  3. package/es/Button/Button.d.ts +2 -1
  4. package/es/Button/Button.js +4 -4
  5. package/es/Checkbox/Checkbox.d.ts +10 -2
  6. package/es/Checkbox/Checkbox.js +35 -5
  7. package/es/Drawer/Drawer.d.ts +10 -0
  8. package/es/Drawer/Drawer.js +14 -0
  9. package/es/Empty/Empty.js +0 -1
  10. package/es/Form/Form.d.ts +2 -1
  11. package/es/Form/Form.js +3 -3
  12. package/es/Form/Form.types.d.ts +9 -0
  13. package/es/Form/FormItem.d.ts +2 -1
  14. package/es/Form/FormItem.js +3 -4
  15. package/es/Form/FormProvider.js +148 -115
  16. package/es/Form/useFormWatch.d.ts +3 -0
  17. package/es/Form/useFormWatch.js +37 -0
  18. package/es/Input/Input.js +3 -3
  19. package/es/Menu/Menu.d.ts +2 -0
  20. package/es/Menu/Menu.js +128 -11
  21. package/es/Modal/Modal.d.ts +2 -0
  22. package/es/Modal/Modal.js +88 -17
  23. package/es/Modal/ModalTemp.js +4 -1
  24. package/es/Pagination/Pagination.d.ts +2 -0
  25. package/es/Pagination/Pagination.js +25 -12
  26. package/es/Quantity/Quantity.d.ts +10 -0
  27. package/es/Quantity/Quantity.js +45 -0
  28. package/es/Radio/Radio.js +0 -1
  29. package/es/Select/Select.d.ts +10 -0
  30. package/es/Select/Select.js +16 -10
  31. package/es/Spin/Spin.d.ts +10 -0
  32. package/es/Spin/Spin.js +23 -0
  33. package/es/Switch/Switch.d.ts +9 -0
  34. package/es/Switch/Switch.js +20 -0
  35. package/es/Table/Table.d.ts +4 -1
  36. package/es/Table/Table.js +22 -8
  37. package/es/Tabs/Tabs.js +0 -1
  38. package/es/Tag/Tag.d.ts +1 -1
  39. package/es/Tag/Tag.js +1 -2
  40. package/es/Toast/Toast.js +0 -1
  41. package/es/Toast/ToastContainer.js +0 -1
  42. package/es/Tooltip/Tooltip.d.ts +2 -0
  43. package/es/Tooltip/Tooltip.js +56 -19
  44. package/es/constants/icons.d.ts +16 -0
  45. package/es/constants/icons.js +17 -1
  46. package/es/index.css +1 -0
  47. package/es/index.d.ts +7 -2
  48. package/es/index.js +6 -0
  49. package/es/node_modules/tslib/tslib.es6.js +39 -1
  50. package/package.json +3 -3
  51. package/es/Button/button.css.js +0 -6
  52. package/es/Checkbox/checkbox.css.js +0 -6
  53. package/es/Empty/empty.css.js +0 -6
  54. package/es/Form/form.css.js +0 -6
  55. package/es/Input/input.css.js +0 -6
  56. package/es/Menu/menu.css.js +0 -6
  57. package/es/Modal/modal.css.js +0 -6
  58. package/es/Pagination/pagination.css.js +0 -6
  59. package/es/Radio/radio.css.js +0 -6
  60. package/es/Table/table.css.js +0 -6
  61. package/es/Tabs/tabs.css.js +0 -6
  62. package/es/Tag/tag.css.js +0 -6
  63. package/es/Toast/toast.css.js +0 -6
  64. package/es/Tooltip/tooltip.css.js +0 -6
  65. package/es/node_modules/style-inject/dist/style-inject.es.js +0 -28
@@ -1,43 +1,56 @@
1
1
  import { __assign } from '../node_modules/tslib/tslib.es6.js';
2
2
  import { jsx } from 'react/jsx-runtime';
3
- import { forwardRef, useState, useRef, useEffect, useCallback, useImperativeHandle } from 'react';
3
+ import { forwardRef, useRef, useState, useEffect, useCallback, useImperativeHandle } from 'react';
4
4
  import { FormContext } from './FormContext.js';
5
5
 
6
6
  var FormProvider = function (_a, ref) {
7
7
  var children = _a.children, _b = _a.initialValues, initialValues = _b === void 0 ? {} : _b;
8
- var _c = useState({}), formFields = _c[0], setFormFields = _c[1];
8
+ var formFieldsRef = useRef({});
9
+ var _c = useState({}), forceUpdate = _c[1]; // Used to force re-render when ref changes
9
10
  var formInstanceRef = useRef({});
11
+ var subscribersRef = useRef([]);
10
12
  // 初始值的设置
11
13
  useEffect(function () {
12
14
  if (Object.keys(initialValues).length > 0) {
13
- setFormFields(function (prevFields) {
14
- var newFields = __assign({}, prevFields);
15
- for (var key in initialValues) {
16
- if (!newFields[key]) {
17
- newFields[key] = { value: initialValues[key], rules: [] };
18
- }
19
- else {
20
- newFields[key] = __assign(__assign({}, newFields[key]), { value: initialValues[key] });
21
- }
15
+ formFieldsRef.current = __assign({}, formFieldsRef.current); // Create a new object
16
+ for (var key in initialValues) {
17
+ if (!formFieldsRef.current[key]) {
18
+ formFieldsRef.current[key] = { value: initialValues[key], rules: [] };
22
19
  }
23
- return newFields;
24
- });
20
+ else {
21
+ formFieldsRef.current[key] = __assign(__assign({}, formFieldsRef.current[key]), { value: initialValues[key] });
22
+ }
23
+ }
24
+ forceUpdate({}); // Trigger re-render
25
25
  }
26
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
+ }, []);
27
43
  // 注册字段
28
44
  var registerField = useCallback(function (name, rules) {
29
- setFormFields(function (prevFields) {
30
- var _a;
31
- return (__assign(__assign({}, prevFields), (_a = {}, _a[name] = __assign(__assign({}, prevFields[name]), { rules: rules || [] }), _a)));
32
- });
45
+ formFieldsRef.current = __assign({}, formFieldsRef.current); // Create a new object
46
+ formFieldsRef.current[name] = __assign(__assign({}, formFieldsRef.current[name]), { rules: rules || [] });
47
+ forceUpdate({}); // Trigger re-render
33
48
  }, []);
34
49
  // 销毁字段
35
50
  var unregisterField = useCallback(function (name) {
36
- setFormFields(function (prevFields) {
37
- var newFields = __assign({}, prevFields);
38
- delete newFields[name];
39
- return newFields;
40
- });
51
+ formFieldsRef.current = __assign({}, formFieldsRef.current); // Create a new object
52
+ delete formFieldsRef.current[name];
53
+ forceUpdate({}); // Trigger re-render
41
54
  }, []);
42
55
  // 验证字段
43
56
  var validateField = useCallback(function (name, value, rules) {
@@ -60,13 +73,17 @@ var FormProvider = function (_a, ref) {
60
73
  if (rule.type === 'string' && typeof value !== 'string') {
61
74
  return { type: 'error', message: rule.message || 'The input is not a string' };
62
75
  }
63
- 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) {
64
79
  return {
65
80
  type: 'error',
66
81
  message: rule.message || "The input is less than ".concat(rule.min, " characters")
67
82
  };
68
83
  }
69
- 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) {
70
87
  return {
71
88
  type: 'error',
72
89
  message: rule.message || "The input is more than ".concat(rule.max, " characters")
@@ -77,140 +94,153 @@ var FormProvider = function (_a, ref) {
77
94
  }, []);
78
95
  // 设置字段值
79
96
  var setFieldsValue = useCallback(function (values) {
80
- setFormFields(function (prevFields) {
81
- var _a;
82
- var newFields = __assign({}, prevFields);
83
- for (var key in values) {
84
- if (Object.prototype.hasOwnProperty.call(values, key)) {
85
- var newValue = values[key];
86
- newFields[key] = __assign(__assign({}, newFields[key]), { value: newValue });
87
- // 验证字段
88
- var validation = validateField(key, newValue, ((_a = newFields[key]) === null || _a === void 0 ? void 0 : _a.rules) || []);
89
- if (validation) {
90
- if (validation.type === 'error') {
91
- newFields[key] = __assign(__assign({}, newFields[key]), { error: validation.message, warning: undefined // Clear any previous warnings
92
- });
93
- }
94
- else if (validation.type === 'warning') {
95
- newFields[key] = __assign(__assign({}, newFields[key]), { warning: validation.message, error: undefined // Clear any previous errors
96
- });
97
- }
97
+ var _a, _b;
98
+ var changedFields = [];
99
+ formFieldsRef.current = __assign({}, formFieldsRef.current); // Create a new object
100
+ for (var key in values) {
101
+ if (Object.prototype.hasOwnProperty.call(values, key)) {
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
+ }
107
+ formFieldsRef.current[key] = __assign(__assign({}, formFieldsRef.current[key]), { value: newValue });
108
+ // 验证字段
109
+ var validation = validateField(key, newValue, ((_b = formFieldsRef.current[key]) === null || _b === void 0 ? void 0 : _b.rules) || []);
110
+ if (validation) {
111
+ if (validation.type === 'error') {
112
+ formFieldsRef.current[key] = __assign(__assign({}, formFieldsRef.current[key]), { error: validation.message, warning: undefined // Clear any previous warnings
113
+ });
98
114
  }
99
- else {
100
- newFields[key] = __assign(__assign({}, newFields[key]), { error: undefined, warning: undefined });
115
+ else if (validation.type === 'warning') {
116
+ formFieldsRef.current[key] = __assign(__assign({}, formFieldsRef.current[key]), { warning: validation.message, error: undefined // Clear any previous errors
117
+ });
101
118
  }
102
119
  }
120
+ else {
121
+ formFieldsRef.current[key] = __assign(__assign({}, formFieldsRef.current[key]), { error: undefined, warning: undefined });
122
+ }
103
123
  }
104
- return newFields;
105
- });
106
- }, [formFields, validateField]);
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
+ }
143
+ forceUpdate({}); // Trigger re-render
144
+ }, [validateField]);
107
145
  // 获取字段值
108
146
  var getFieldsValue = useCallback(function (names) {
109
147
  if (!names) {
110
- return Object.keys(formFields).reduce(function (acc, key) {
111
- acc[key] = formFields[key].value;
148
+ return Object.keys(formFieldsRef.current).reduce(function (acc, key) {
149
+ acc[key] = formFieldsRef.current[key].value;
112
150
  return acc;
113
151
  }, {});
114
152
  }
115
153
  return names.reduce(function (acc, key) {
116
154
  var _a;
117
- acc[key] = (_a = formFields[key]) === null || _a === void 0 ? void 0 : _a.value;
155
+ acc[key] = (_a = formFieldsRef.current[key]) === null || _a === void 0 ? void 0 : _a.value;
118
156
  return acc;
119
157
  }, {});
120
- }, [formFields]);
158
+ }, []);
121
159
  // 重置字段
122
160
  var resetFields = useCallback(function (names) {
123
- setFormFields(function (prevFields) {
124
- var newFields = __assign({}, prevFields);
125
- if (names) {
126
- names.forEach(function (name) {
127
- if (newFields[name]) {
128
- newFields[name].value = initialValues[name] || '';
129
- newFields[name].error = undefined;
130
- newFields[name].warning = undefined;
131
- }
132
- });
133
- }
134
- else {
135
- Object.keys(newFields).forEach(function (key) {
136
- newFields[key].value = initialValues[key] || '';
137
- newFields[key].error = undefined;
138
- newFields[key].warning = undefined;
139
- });
140
- }
141
- return newFields;
142
- });
143
- }, [formFields, initialValues]);
161
+ formFieldsRef.current = __assign({}, formFieldsRef.current); // Create a new object
162
+ if (names) {
163
+ names.forEach(function (name) {
164
+ if (formFieldsRef.current[name]) {
165
+ formFieldsRef.current[name].value = initialValues[name] || '';
166
+ formFieldsRef.current[name].error = undefined;
167
+ formFieldsRef.current[name].warning = undefined;
168
+ }
169
+ });
170
+ }
171
+ else {
172
+ Object.keys(formFieldsRef.current).forEach(function (key) {
173
+ formFieldsRef.current[key].value = initialValues[key] || '';
174
+ formFieldsRef.current[key].error = undefined;
175
+ formFieldsRef.current[key].warning = undefined;
176
+ });
177
+ }
178
+ forceUpdate({}); // Trigger re-render
179
+ }, [initialValues]);
144
180
  var validateFields = useCallback(function (names) {
145
181
  return new Promise(function (resolve, reject) {
146
- var fieldsToValidate = names || Object.keys(formFields);
182
+ var fieldsToValidate = names || Object.keys(formFieldsRef.current);
147
183
  var values = getFieldsValue(fieldsToValidate);
148
184
  var errors = {};
149
185
  for (var _i = 0, fieldsToValidate_1 = fieldsToValidate; _i < fieldsToValidate_1.length; _i++) {
150
186
  var key = fieldsToValidate_1[_i];
151
- var field = formFields[key];
187
+ var field = formFieldsRef.current[key];
152
188
  if (!field)
153
189
  continue; // Skip if field is not registered
154
190
  var validation = validateField(key, values[key], field.rules || []);
155
- if (validation) {
156
- if (validation.type === 'error') {
157
- 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 || '';
158
194
  }
159
- else if (validation.type === 'warning') {
160
- 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 || '';
161
197
  }
162
198
  }
163
199
  }
164
200
  if (Object.keys(errors).length > 0) {
165
- setFormFields(function (prevFields) {
166
- var newFields = __assign({}, prevFields);
167
- for (var key in errors) {
168
- newFields[key] = __assign(__assign({}, newFields[key]), { error: errors[key] });
169
- }
170
- return newFields;
171
- });
201
+ formFieldsRef.current = __assign({}, formFieldsRef.current); // Create a new object
202
+ for (var key in errors) {
203
+ formFieldsRef.current[key] = __assign(__assign({}, formFieldsRef.current[key]), { error: errors[key] });
204
+ }
205
+ forceUpdate({}); // Trigger re-render
172
206
  reject(errors);
173
207
  }
174
208
  else {
175
209
  resolve(values);
176
210
  }
177
211
  });
178
- }, [formFields, getFieldsValue, validateField]);
212
+ }, [getFieldsValue, validateField]);
179
213
  var setFieldsStatus = useCallback(function (status) {
180
- setFormFields(function (prevFields) {
181
- var newFields = __assign({}, prevFields);
182
- status.forEach(function (_a) {
183
- var type = _a.type, name = _a.name, message = _a.message;
184
- if (Array.isArray(name)) {
185
- name.forEach(function (n) {
186
- if (newFields[n]) {
187
- // Only update if field exists
188
- if (type === 'error') {
189
- newFields[n] = __assign(__assign({}, newFields[n]), { error: message });
190
- }
191
- else if (type === 'warning') {
192
- newFields[n] = __assign(__assign({}, newFields[n]), { warning: message });
193
- }
194
- }
195
- });
196
- }
197
- else {
198
- if (newFields[name]) {
214
+ formFieldsRef.current = __assign({}, formFieldsRef.current); // Create a new object
215
+ status.forEach(function (_a) {
216
+ var type = _a.type, name = _a.name, message = _a.message;
217
+ if (Array.isArray(name)) {
218
+ name.forEach(function (n) {
219
+ if (formFieldsRef.current[n]) {
199
220
  // Only update if field exists
200
221
  if (type === 'error') {
201
- newFields[name] = __assign(__assign({}, newFields[name]), { error: message });
222
+ formFieldsRef.current[n] = __assign(__assign({}, formFieldsRef.current[n]), { error: message });
202
223
  }
203
224
  else if (type === 'warning') {
204
- newFields[name] = __assign(__assign({}, newFields[name]), { warning: message });
225
+ formFieldsRef.current[n] = __assign(__assign({}, formFieldsRef.current[n]), { warning: message });
205
226
  }
206
227
  }
228
+ });
229
+ }
230
+ else {
231
+ if (formFieldsRef.current[name]) {
232
+ // Only update if field exists
233
+ if (type === 'error') {
234
+ formFieldsRef.current[name] = __assign(__assign({}, formFieldsRef.current[name]), { error: message });
235
+ }
236
+ else if (type === 'warning') {
237
+ formFieldsRef.current[name] = __assign(__assign({}, formFieldsRef.current[name]), { warning: message });
238
+ }
207
239
  }
208
- });
209
- return newFields;
240
+ }
210
241
  });
211
- }, [formFields]);
212
- // 暴露给外部的方法
213
- useImperativeHandle(ref, function () { return (__assign({}, formInstanceRef.current)); });
242
+ forceUpdate({}); // Trigger re-render
243
+ }, []);
214
244
  formInstanceRef.current = {
215
245
  setFieldsValue: setFieldsValue,
216
246
  getFieldsValue: getFieldsValue,
@@ -218,9 +248,12 @@ var FormProvider = function (_a, ref) {
218
248
  validateFields: validateFields,
219
249
  setFieldsStatus: setFieldsStatus,
220
250
  registerField: registerField,
221
- unregisterField: unregisterField
251
+ unregisterField: unregisterField,
252
+ subscribe: subscribe
222
253
  };
223
- return (jsx(FormContext.Provider, __assign({ value: { form: formInstanceRef.current, formFields: formFields } }, { children: children })));
254
+ // 暴露给外部的方法
255
+ useImperativeHandle(ref, function () { return (__assign({}, formInstanceRef.current)); });
256
+ return (jsx(FormContext.Provider, __assign({ value: { form: formInstanceRef.current, formFields: formFieldsRef.current } }, { children: children })));
224
257
  };
225
258
  var FormProvider$1 = forwardRef(FormProvider);
226
259
 
@@ -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/Input/Input.js CHANGED
@@ -2,7 +2,6 @@ import { __rest, __assign } from '../node_modules/tslib/tslib.es6.js';
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { useState } from 'react';
4
4
  import classNames from 'classnames';
5
- import './input.css.js';
6
5
  import { Icon } from '../Icon/index.js';
7
6
 
8
7
  var Input = function (_a) {
@@ -11,12 +10,13 @@ var Input = function (_a) {
11
10
  };
12
11
  var SearchInput = function (_a) {
13
12
  var onSearch = _a.onSearch, rest = __rest(_a, ["onSearch"]);
13
+ var _b = useState(rest.value || ''), value = _b[0], setValue = _b[1];
14
14
  var handleSearch = function () {
15
15
  if (onSearch) {
16
- onSearch(rest.value);
16
+ onSearch(value);
17
17
  }
18
18
  };
19
- return (jsx(Input, __assign({}, rest, { addonAfter: jsx("div", __assign({ style: { display: 'flex' }, onClick: handleSearch }, { children: jsx(Icon, { name: "SearchOutlined" }) })) })));
19
+ return (jsx(Input, __assign({}, rest, { onChange: function (e) { return setValue(e.target.value); }, addonAfter: jsx("div", __assign({ style: { display: 'flex' }, onClick: handleSearch }, { children: jsx(Icon, { name: "SearchOutlined" }) })) })));
20
20
  };
21
21
  var PasswordInput = function (props) {
22
22
  var _a = useState(false), visible = _a[0], setVisible = _a[1];
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,8 +1,7 @@
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
- import './menu.css.js';
6
5
 
7
6
  var getItem = function (label, key, icon, children, type) {
8
7
  return {
@@ -14,23 +13,30 @@ var getItem = function (label, key, icon, children, type) {
14
13
  };
15
14
  };
16
15
  var Menu = function (_a) {
17
- 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;
18
- var _d = useState(defaultOpenKeys), openKeys = _d[0], setOpenKeys = _d[1];
19
- 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);
20
25
  var handleMenuClick = function (e) {
21
26
  onClick === null || onClick === void 0 ? void 0 : onClick(e);
22
- setSelectedKeys([e.key]);
27
+ if (controlledSelectedKeys === undefined) {
28
+ setUncontrolledSelectedKeys([e.key]);
29
+ }
23
30
  };
24
- // const handleOpenChange = (keys: string[]) => {
25
- // setOpenKeys(keys);
26
- // };
27
31
  var isFirstLevel = function (item) {
28
32
  return items.some(function (i) { return i.key === item.key; });
29
33
  };
34
+ // 标准展开模式的菜单项渲染
30
35
  var renderMenuItem = function (item) {
31
36
  var isSelected = selectedKeys.includes(item.key.toString());
32
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));
33
38
  };
39
+ // 标准展开模式的子菜单渲染
34
40
  var renderSubMenu = function (item) {
35
41
  var isOpen = openKeys.includes(item.key.toString());
36
42
  return (jsxs("div", { children: [jsxs("div", __assign({ className: "foxit-menu-submenu-title", onClick: function () {
@@ -44,7 +50,118 @@ var Menu = function (_a) {
44
50
  return child.children ? renderSubMenu(child) : renderMenuItem(child);
45
51
  }) })))] }, item.key));
46
52
  };
47
- 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()] }));
48
165
  };
49
166
 
50
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 & {