@fe-free/core 3.0.17 → 3.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @fe-free/core
2
2
 
3
+ ## 3.0.19
4
+
5
+ ### Patch Changes
6
+
7
+ - feat: pro form list
8
+ - @fe-free/tool@3.0.19
9
+
10
+ ## 3.0.18
11
+
12
+ ### Patch Changes
13
+
14
+ - feat: rules
15
+ - @fe-free/tool@3.0.18
16
+
3
17
  ## 3.0.17
4
18
 
5
19
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fe-free/core",
3
- "version": "3.0.17",
3
+ "version": "3.0.19",
4
4
  "description": "",
5
5
  "main": "./src/index.ts",
6
6
  "author": "",
@@ -41,7 +41,7 @@
41
41
  "safe-stable-stringify": "^2.5.0",
42
42
  "vanilla-jsoneditor": "^0.23.1",
43
43
  "zustand": "^4.5.4",
44
- "@fe-free/tool": "3.0.17"
44
+ "@fe-free/tool": "3.0.19"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@ant-design/pro-components": "2.8.9",
@@ -16,6 +16,7 @@ import {
16
16
  ProFormUpload,
17
17
  ProFormUploadDragger,
18
18
  } from '@fe-free/core';
19
+ import { sleep } from '@fe-free/tool';
19
20
  import type { Meta, StoryObj } from '@storybook/react-vite';
20
21
  import { useState } from 'react';
21
22
 
@@ -169,6 +170,7 @@ export const ProFormListTextComponent: Story = {
169
170
  render: () => (
170
171
  <ProFormBase>
171
172
  <ProFormListText name="listText" />
173
+ <ProFormListText name="listText_isValueLabel" fieldProps={{ isValueLabel: true }} />
172
174
  </ProFormBase>
173
175
  ),
174
176
  };
@@ -177,7 +179,12 @@ export const ProFormListNumberComponent: Story = {
177
179
  render: () => (
178
180
  <ProFormBase>
179
181
  <ProFormListNumber name="listNumber" label="listNumber" />
182
+ <ProFormListNumber name="listNumber_isValueLabel" fieldProps={{ isValueLabel: true }} />
180
183
  <ProFormListNumber name="listInteger" label="listInteger" fieldProps={{ precision: 0 }} />
184
+ <ProFormListNumber
185
+ name="listInteger_isValueLabel"
186
+ fieldProps={{ isValueLabel: true, precision: 0 }}
187
+ />
181
188
  </ProFormBase>
182
189
  ),
183
190
  };
@@ -191,31 +198,19 @@ export const ProFormListBooleanComponent: Story = {
191
198
  };
192
199
 
193
200
  function customRequest(option: any) {
194
- const { file, onProgress, onSuccess } = option;
195
-
196
- // 模拟上传进度
197
- let percent = 0;
198
- const interval = setInterval(() => {
199
- percent += 10;
200
- onProgress({ percent });
201
-
202
- if (percent >= 100) {
203
- clearInterval(interval);
204
- // 模拟上传成功
205
- onSuccess({
206
- data: {
207
- url: `https://picsum.photos/200/300?random=${Date.now()}`,
208
- name: file.name,
209
- uid: file.uid,
210
- },
211
- });
212
- }
213
- }, 1000);
201
+ const { onSuccess } = option;
202
+ // fake request
203
+ sleep(1000).then(() => {
204
+ onSuccess({
205
+ data: {
206
+ url: `https://picsum.photos/200/300?random=${Date.now()}`,
207
+ },
208
+ });
209
+ });
214
210
 
215
211
  // 返回 abort 方法,用于取消上传
216
212
  return {
217
213
  abort: () => {
218
- clearInterval(interval);
219
214
  console.log('上传已取消');
220
215
  },
221
216
  };
@@ -2,6 +2,7 @@ import type { ProFormItemProps } from '@ant-design/pro-components';
2
2
  import { ProForm } from '@ant-design/pro-components';
3
3
  import { Input, InputNumber, Switch } from 'antd';
4
4
 
5
+ import { uniq, uniqBy } from 'lodash-es';
5
6
  import { ProFormListHelper } from './form_list_helper';
6
7
 
7
8
  interface ListTextProps {
@@ -13,8 +14,18 @@ interface ListTextProps {
13
14
 
14
15
  function ListText(props: ListTextProps) {
15
16
  const { isValueLabel, placeholder } = props;
17
+
16
18
  return (
17
- <ProFormListHelper value={props.value} onChange={props.onChange} getAdd={() => ''}>
19
+ <ProFormListHelper
20
+ value={props.value}
21
+ onChange={props.onChange}
22
+ getAdd={() => {
23
+ if (isValueLabel) {
24
+ return { value: '', label: '' };
25
+ }
26
+ return '';
27
+ }}
28
+ >
18
29
  {({ item, onItemChange }) => {
19
30
  // @ts-ignore
20
31
  const value = isValueLabel ? item.value : item;
@@ -47,7 +58,16 @@ interface ListNumberProps {
47
58
  function ListNumber(props: ListNumberProps) {
48
59
  const { isValueLabel, placeholder, precision } = props;
49
60
  return (
50
- <ProFormListHelper value={props.value} onChange={props.onChange} getAdd={() => 0}>
61
+ <ProFormListHelper
62
+ value={props.value}
63
+ onChange={props.onChange}
64
+ getAdd={() => {
65
+ if (isValueLabel) {
66
+ return { value: 0, label: '0' };
67
+ }
68
+ return 0;
69
+ }}
70
+ >
51
71
  {({ item, onItemChange }) => {
52
72
  // @ts-ignore
53
73
  const value = isValueLabel ? item.value : item;
@@ -86,11 +106,9 @@ function ListBoolean(props: ListBooleanProps) {
86
106
  );
87
107
  }
88
108
 
89
- function ProFormListBase(props) {
109
+ function ProFormListText(props: ProFormItemProps<ListTextProps>) {
90
110
  const { fieldProps, ...rest } = props;
91
111
 
92
- const isValueLabel = fieldProps?.isValueLabel;
93
-
94
112
  return (
95
113
  <ProForm.Item
96
114
  {...rest}
@@ -100,13 +118,21 @@ function ProFormListBase(props) {
100
118
  // { required: true },
101
119
  {
102
120
  validator: async (_, value) => {
103
- if (isValueLabel) {
104
- if (value?.some((item) => item.value === undefined)) {
105
- return Promise.reject('每个选项都不能为空');
121
+ if (fieldProps?.isValueLabel) {
122
+ if (value?.some((item) => item.value === undefined || item.value === '')) {
123
+ return Promise.reject('存在空选项');
124
+ }
125
+ // 不能有重复的 value
126
+ if (uniqBy(value, 'value').length !== value.length) {
127
+ return Promise.reject('不能有重复');
106
128
  }
107
129
  } else {
108
- if (value?.some((item) => item === undefined)) {
109
- return Promise.reject('每个选项都不能为空');
130
+ if (value?.some((item) => item === undefined || item === '')) {
131
+ return Promise.reject('存在空选项');
132
+ }
133
+ // 不能有重复的 value
134
+ if (uniq(value).length !== value.length) {
135
+ return Promise.reject('不能有重复');
110
136
  }
111
137
  }
112
138
  return Promise.resolve();
@@ -114,18 +140,8 @@ function ProFormListBase(props) {
114
140
  },
115
141
  ]}
116
142
  >
117
- {props.children}
118
- </ProForm.Item>
119
- );
120
- }
121
-
122
- function ProFormListText(props: ProFormItemProps<ListTextProps>) {
123
- const { fieldProps, ...rest } = props;
124
-
125
- return (
126
- <ProFormListBase {...rest}>
127
143
  <ListText {...fieldProps} />
128
- </ProFormListBase>
144
+ </ProForm.Item>
129
145
  );
130
146
  }
131
147
 
@@ -133,18 +149,47 @@ function ProFormListNumber(props: ProFormItemProps<ListNumberProps>) {
133
149
  const { fieldProps, ...rest } = props;
134
150
 
135
151
  return (
136
- <ProFormListBase {...rest}>
152
+ <ProForm.Item
153
+ {...rest}
154
+ required={props.required ?? true}
155
+ rules={[
156
+ ...(props.rules || []),
157
+ // { required: true },
158
+ {
159
+ validator: async (_, value) => {
160
+ if (fieldProps?.isValueLabel) {
161
+ if (value?.some((item) => item.value === undefined || item.value === null)) {
162
+ return Promise.reject('存在空选项');
163
+ }
164
+ // 不能有重复的 value
165
+ if (uniqBy(value, 'value').length !== value.length) {
166
+ return Promise.reject('不能有重复');
167
+ }
168
+ } else {
169
+ if (value?.some((item) => item === undefined || item === null)) {
170
+ return Promise.reject('存在空选项');
171
+ }
172
+ // 不能有重复的 value
173
+ if (uniq(value).length !== value.length) {
174
+ return Promise.reject('不能有重复');
175
+ }
176
+ }
177
+ return Promise.resolve();
178
+ },
179
+ },
180
+ ]}
181
+ >
137
182
  <ListNumber {...fieldProps} />
138
- </ProFormListBase>
183
+ </ProForm.Item>
139
184
  );
140
185
  }
141
186
 
142
187
  function ProFormListBoolean(props: ProFormItemProps<ListBooleanProps>) {
143
188
  const { fieldProps, ...rest } = props;
144
189
  return (
145
- <ProFormListBase {...rest}>
190
+ <ProForm.Item {...rest} required={props.required ?? true}>
146
191
  <ListBoolean {...fieldProps} />
147
- </ProFormListBase>
192
+ </ProForm.Item>
148
193
  );
149
194
  }
150
195
 
@@ -41,7 +41,7 @@ function useUpload(
41
41
  const [fileList, setFileList] = useState<UploadFile[]>(defaultFileList);
42
42
 
43
43
  // 找到真正上传成功的。
44
- const successList = fileList.map((item) => item.url || item.response?.data.url).filter(Boolean);
44
+ const successList = fileList.map((item) => item.url || item.response?.data?.url).filter(Boolean);
45
45
 
46
46
  const handleChange = useCallback(
47
47
  (info) => {
@@ -49,7 +49,7 @@ function useUpload(
49
49
 
50
50
  // 找到真正上传成功的。
51
51
  const newValue = info.fileList
52
- .map((item) => item.url || item.response?.data.url)
52
+ .map((item) => item.url || item.response?.data?.url)
53
53
  .filter(Boolean);
54
54
 
55
55
  onChange?.(multiple ? newValue : newValue[0]);
@@ -245,7 +245,7 @@ function AvatarImageUpload(props: AvatarImageUploadProps) {
245
245
  action={action}
246
246
  customRequest={customRequest}
247
247
  onChange={(info) => {
248
- const url = info.file.response?.data.url;
248
+ const url = info.file.response?.data?.url;
249
249
  if (url) {
250
250
  onChange?.(url);
251
251
  }