@fe-free/core 3.0.9 → 3.0.11
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 +14 -0
- package/package.json +2 -2
- package/src/crud/crud.stories.tsx +4 -2
- package/src/crud/crud.tsx +7 -14
- package/src/crud/index.tsx +1 -1
- package/src/crud/types.tsx +9 -7
- package/src/crud_of_list/crud_of_list.stories.tsx +24 -17
- package/src/crud_of_list/index.tsx +3 -11
- package/src/crud_of_pure/index.tsx +3 -11
- package/src/file/file.stories.tsx +6 -4
- package/src/file/index.tsx +8 -3
- package/src/index.ts +1 -1
- package/src/style.scss +16 -4
- package/src/tree/file_tree.stories.tsx +1 -1
- package/src/tree/file_tree.tsx +3 -0
- package/src/tree/tree.tsx +2 -2
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fe-free/core",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.11",
|
|
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.
|
|
44
|
+
"@fe-free/tool": "3.0.11"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@ant-design/pro-components": "2.8.9",
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ProColumns } from '@ant-design/pro-components';
|
|
2
2
|
import { ProForm, ProFormSwitch, ProFormText } from '@ant-design/pro-components';
|
|
3
|
+
import type { CRUDRef } from '@fe-free/core';
|
|
3
4
|
import { CRUD, proFormSelectSearchProps } from '@fe-free/core';
|
|
5
|
+
|
|
4
6
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
5
7
|
import { Button } from 'antd';
|
|
6
8
|
import { useRef } from 'react';
|
|
@@ -286,7 +288,7 @@ export const FormRef: Story = {
|
|
|
286
288
|
|
|
287
289
|
// 通过 ref 获取 actionRef
|
|
288
290
|
const ActionRefComponent = () => {
|
|
289
|
-
const ref = useRef<
|
|
291
|
+
const ref = useRef<CRUDRef | null>(null);
|
|
290
292
|
|
|
291
293
|
const columns = [
|
|
292
294
|
{
|
|
@@ -303,7 +305,7 @@ const ActionRefComponent = () => {
|
|
|
303
305
|
|
|
304
306
|
return (
|
|
305
307
|
<>
|
|
306
|
-
<Button onClick={() => ref.current
|
|
308
|
+
<Button onClick={() => ref.current?.getActionRef()?.current?.reload()}>reload</Button>
|
|
307
309
|
<CRUD
|
|
308
310
|
ref={ref}
|
|
309
311
|
actions={[]}
|
package/src/crud/crud.tsx
CHANGED
|
@@ -3,21 +3,20 @@ import type { ActionType } from '@ant-design/pro-components';
|
|
|
3
3
|
import { Button, message } from 'antd';
|
|
4
4
|
import classNames from 'classnames';
|
|
5
5
|
import { isString } from 'lodash-es';
|
|
6
|
-
import {
|
|
6
|
+
import { useCallback, useImperativeHandle, useMemo, useRef } from 'react';
|
|
7
7
|
import { Link } from 'react-router-dom';
|
|
8
8
|
import type { TableProps } from '../table';
|
|
9
9
|
import { getTableScroll, Table } from '../table';
|
|
10
10
|
import { OperateDelete } from './crud_delete';
|
|
11
11
|
import { CRUDDetail } from './crud_detail';
|
|
12
12
|
import './style.scss';
|
|
13
|
-
import type {
|
|
13
|
+
import type { CRUDProps } from './types';
|
|
14
14
|
import { useRowSelection } from './use_row_selection';
|
|
15
15
|
import { useTips } from './use_tips';
|
|
16
16
|
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
>(props: CRUDProps<DataSource, Key>, ref: React.ForwardedRef<CRUDMethods>) {
|
|
17
|
+
function CRUD<DataSource extends Record<string, any> = any, Key extends string | number = string>(
|
|
18
|
+
props: CRUDProps<DataSource, Key>,
|
|
19
|
+
) {
|
|
21
20
|
const {
|
|
22
21
|
actions,
|
|
23
22
|
tableProps,
|
|
@@ -39,6 +38,7 @@ function CRUDComponent<
|
|
|
39
38
|
batchActions: originBatchActions,
|
|
40
39
|
fullPage,
|
|
41
40
|
className,
|
|
41
|
+
ref,
|
|
42
42
|
} = props;
|
|
43
43
|
|
|
44
44
|
useTips(props);
|
|
@@ -210,7 +210,7 @@ function CRUDComponent<
|
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
return (
|
|
213
|
-
<div className="fec-crud-operate-column flex gap-2">
|
|
213
|
+
<div className="fec-crud-operate-column flex justify-center gap-2">
|
|
214
214
|
{operateColumnProps?.moreOperator && operateColumnProps.moreOperator(record)}
|
|
215
215
|
{btns}
|
|
216
216
|
{operateColumnProps?.moreOperatorAfter && operateColumnProps.moreOperatorAfter(record)}
|
|
@@ -330,11 +330,4 @@ function CRUDComponent<
|
|
|
330
330
|
);
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
-
const CRUD = forwardRef(CRUDComponent) as <
|
|
334
|
-
DataSource extends Record<string, any> = any,
|
|
335
|
-
Key extends string | number = string,
|
|
336
|
-
>(
|
|
337
|
-
props: CRUDProps<DataSource, Key> & { ref?: React.ForwardedRef<CRUDMethods> },
|
|
338
|
-
) => JSX.Element;
|
|
339
|
-
|
|
340
333
|
export { CRUD };
|
package/src/crud/index.tsx
CHANGED
|
@@ -2,4 +2,4 @@ export { CRUD } from './crud';
|
|
|
2
2
|
export { OperateDelete, useDelete } from './crud_delete';
|
|
3
3
|
export { CRUDDetail } from './crud_detail';
|
|
4
4
|
export type { CRUDDetailProps } from './crud_detail';
|
|
5
|
-
export type {
|
|
5
|
+
export type { CRUDProps, CRUDRef } from './types';
|
package/src/crud/types.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ActionType, ProFormInstance } from '@ant-design/pro-components';
|
|
2
|
-
import type { ReactNode } from 'react';
|
|
2
|
+
import type { MouseEvent, ReactNode, Ref, RefObject } from 'react';
|
|
3
3
|
import type { TableProps } from '../table';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -12,7 +12,13 @@ import type { TableProps } from '../table';
|
|
|
12
12
|
*/
|
|
13
13
|
type CRUDAction = 'create' | 'read' | 'read_detail' | 'update' | 'delete' | 'batch_delete';
|
|
14
14
|
|
|
15
|
+
interface CRUDRef {
|
|
16
|
+
getActionRef: () => RefObject<ActionType | undefined>;
|
|
17
|
+
}
|
|
18
|
+
|
|
15
19
|
interface CRUDProps<DataSource = any, Key = string> {
|
|
20
|
+
ref?: Ref<CRUDRef>;
|
|
21
|
+
|
|
16
22
|
/** 操作类型 */
|
|
17
23
|
actions: CRUDAction[];
|
|
18
24
|
|
|
@@ -131,7 +137,7 @@ interface CRUDProps<DataSource = any, Key = string> {
|
|
|
131
137
|
danger?: boolean;
|
|
132
138
|
/** 批量操作接口 */
|
|
133
139
|
onClick: (
|
|
134
|
-
event:
|
|
140
|
+
event: MouseEvent<HTMLElement>,
|
|
135
141
|
options: { selectedRowKeys: Key[]; selectedRows: DataSource[] },
|
|
136
142
|
) => Promise<void>;
|
|
137
143
|
}[];
|
|
@@ -140,8 +146,4 @@ interface CRUDProps<DataSource = any, Key = string> {
|
|
|
140
146
|
className?: string;
|
|
141
147
|
}
|
|
142
148
|
|
|
143
|
-
|
|
144
|
-
getActionRef: () => React.MutableRefObject<ActionType | undefined>;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
export type { CRUDMethods, CRUDProps };
|
|
149
|
+
export type { CRUDProps, CRUDRef };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ProFormText } from '@ant-design/pro-components';
|
|
2
|
+
import type { CRUDRef } from '@fe-free/core';
|
|
2
3
|
import { CRUDOfList } from '@fe-free/core';
|
|
3
4
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
5
|
+
import { useRef } from 'react';
|
|
4
6
|
import { fakeCreate, fakeDeleteByRecord, fakeRequest } from '../crud/demo/data';
|
|
5
7
|
|
|
6
8
|
const meta: Meta<typeof CRUDOfList> = {
|
|
@@ -35,6 +37,7 @@ type Story = StoryObj<typeof CRUDOfList>;
|
|
|
35
37
|
|
|
36
38
|
export const Basic: Story = {
|
|
37
39
|
render: () => {
|
|
40
|
+
const ref = useRef<CRUDRef>(null);
|
|
38
41
|
const columns = [
|
|
39
42
|
{
|
|
40
43
|
title: '名字(省略)',
|
|
@@ -45,23 +48,27 @@ export const Basic: Story = {
|
|
|
45
48
|
];
|
|
46
49
|
|
|
47
50
|
return (
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
51
|
+
<div>
|
|
52
|
+
<button onClick={() => ref.current?.getActionRef()?.current?.reload()}>reload</button>
|
|
53
|
+
<CRUDOfList
|
|
54
|
+
ref={ref}
|
|
55
|
+
actions={[]}
|
|
56
|
+
tableProps={{
|
|
57
|
+
columns,
|
|
58
|
+
request: fakeRequest,
|
|
59
|
+
}}
|
|
60
|
+
requestDeleteByRecord={fakeDeleteByRecord}
|
|
61
|
+
deleteProps={{
|
|
62
|
+
nameIndex: 'name',
|
|
63
|
+
}}
|
|
64
|
+
detailForm={() => (
|
|
65
|
+
<>
|
|
66
|
+
<ProFormText name="name" label="名字" required rules={[{ required: true }]} />
|
|
67
|
+
</>
|
|
68
|
+
)}
|
|
69
|
+
requestCreateByValues={fakeCreate}
|
|
70
|
+
/>
|
|
71
|
+
</div>
|
|
65
72
|
);
|
|
66
73
|
},
|
|
67
74
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useDebounce } from 'ahooks';
|
|
2
2
|
import { Input } from 'antd';
|
|
3
3
|
import classNames from 'classnames';
|
|
4
|
-
import {
|
|
5
|
-
import type {
|
|
4
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
5
|
+
import type { CRUDProps } from '../crud';
|
|
6
6
|
import { CRUD } from '../crud';
|
|
7
7
|
import './style.scss';
|
|
8
8
|
|
|
@@ -42,7 +42,7 @@ function SearchRender(props: {
|
|
|
42
42
|
);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
function
|
|
45
|
+
function CRUDOfList(props: CRUDOfListProps) {
|
|
46
46
|
useTips(props);
|
|
47
47
|
|
|
48
48
|
const { tableProps, ...rest } = props;
|
|
@@ -85,7 +85,6 @@ function CRUDOfListComponent(props: CRUDOfListProps, ref: React.ForwardedRef<CRU
|
|
|
85
85
|
|
|
86
86
|
return (
|
|
87
87
|
<CRUD
|
|
88
|
-
ref={ref}
|
|
89
88
|
{...rest}
|
|
90
89
|
className={classNames(
|
|
91
90
|
'fec-crud-of-list',
|
|
@@ -115,12 +114,5 @@ function CRUDOfListComponent(props: CRUDOfListProps, ref: React.ForwardedRef<CRU
|
|
|
115
114
|
);
|
|
116
115
|
}
|
|
117
116
|
|
|
118
|
-
const CRUDOfList = forwardRef(CRUDOfListComponent) as <
|
|
119
|
-
DataSource extends Record<string, any> = any,
|
|
120
|
-
Key extends string | number = string,
|
|
121
|
-
>(
|
|
122
|
-
props: CRUDOfListProps<DataSource, Key> & { ref?: React.ForwardedRef<CRUDMethods> },
|
|
123
|
-
) => JSX.Element;
|
|
124
|
-
|
|
125
117
|
export { CRUDOfList };
|
|
126
118
|
export type { CRUDOfListProps };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import classNames from 'classnames';
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import type { CRUDProps } from '../crud';
|
|
4
4
|
import { CRUD } from '../crud';
|
|
5
5
|
import './style.scss';
|
|
6
6
|
|
|
@@ -13,7 +13,7 @@ interface CRUDOfPureProps<
|
|
|
13
13
|
specialToolbar?: boolean;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
function
|
|
16
|
+
function CRUDOfPure(props: CRUDOfPureProps) {
|
|
17
17
|
const newColumns = props.tableProps.columns?.map((column) => {
|
|
18
18
|
if (column.search) {
|
|
19
19
|
return {
|
|
@@ -40,7 +40,6 @@ function CRUDOfPureComponent(props: CRUDOfPureProps, ref: React.ForwardedRef<CRU
|
|
|
40
40
|
|
|
41
41
|
return (
|
|
42
42
|
<CRUD
|
|
43
|
-
ref={ref}
|
|
44
43
|
{...props}
|
|
45
44
|
className={classNames(
|
|
46
45
|
'fec-crud-of-pure',
|
|
@@ -67,12 +66,5 @@ function CRUDOfPureComponent(props: CRUDOfPureProps, ref: React.ForwardedRef<CRU
|
|
|
67
66
|
);
|
|
68
67
|
}
|
|
69
68
|
|
|
70
|
-
const CRUDOfPure = forwardRef(CRUDOfPureComponent) as <
|
|
71
|
-
DataSource extends Record<string, any> = any,
|
|
72
|
-
Key extends string | number = string,
|
|
73
|
-
>(
|
|
74
|
-
props: CRUDOfPureProps<DataSource, Key> & { ref?: React.ForwardedRef<CRUDMethods> },
|
|
75
|
-
) => JSX.Element;
|
|
76
|
-
|
|
77
69
|
export { CRUDOfPure };
|
|
78
70
|
export type { CRUDOfPureProps };
|
|
@@ -16,11 +16,13 @@ export const Default: Story = {
|
|
|
16
16
|
let size = 0;
|
|
17
17
|
return (
|
|
18
18
|
<div>
|
|
19
|
-
<div className="flex flex-col gap-2">
|
|
19
|
+
<div className="flex w-[200px] flex-col gap-2 border border-01">
|
|
20
20
|
{PRESET_FILE_ICONS.map((item) => (
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
<FileCard
|
|
22
|
+
key={item.key}
|
|
23
|
+
name={`这是文件名.${item.ext.join('.') || ''}`}
|
|
24
|
+
size={(size += 1000000)}
|
|
25
|
+
/>
|
|
24
26
|
))}
|
|
25
27
|
</div>
|
|
26
28
|
</div>
|
package/src/file/index.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Typography } from 'antd';
|
|
1
2
|
import classNames from 'classnames';
|
|
2
3
|
import { useMemo } from 'react';
|
|
3
4
|
import {
|
|
@@ -54,9 +55,13 @@ function FileCard({
|
|
|
54
55
|
'flex-col': direction === 'vertical',
|
|
55
56
|
})}
|
|
56
57
|
>
|
|
57
|
-
<FileIcon name={name} className="text-
|
|
58
|
-
<div
|
|
59
|
-
{
|
|
58
|
+
<FileIcon name={name} className="text-3xl" />
|
|
59
|
+
<div
|
|
60
|
+
className={classNames('flex flex-1 flex-col overflow-hidden', {
|
|
61
|
+
'items-center': direction === 'vertical',
|
|
62
|
+
})}
|
|
63
|
+
>
|
|
64
|
+
{name && <Typography.Text ellipsis={{ tooltip: name }}>{name}</Typography.Text>}
|
|
60
65
|
{size && <div className="text-sm text-03">{getFileSize(size)}</div>}
|
|
61
66
|
</div>
|
|
62
67
|
</div>
|
package/src/index.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { Copy } from './copy';
|
|
|
7
7
|
export type { CopyProps } from './copy';
|
|
8
8
|
export { CoreApp } from './core_app';
|
|
9
9
|
export { CRUD, CRUDDetail, OperateDelete, useDelete } from './crud';
|
|
10
|
-
export type { CRUDDetailProps,
|
|
10
|
+
export type { CRUDDetailProps, CRUDProps, CRUDRef } from './crud';
|
|
11
11
|
export { CRUDOfList } from './crud_of_list';
|
|
12
12
|
export type { CRUDOfListProps } from './crud_of_list';
|
|
13
13
|
export { CRUDOfPure } from './crud_of_pure';
|
package/src/style.scss
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// base
|
|
6
6
|
* {
|
|
7
7
|
border: 0 solid;
|
|
8
|
+
box-sizing: border-box;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
/* stylelint-disable-next-line at-rule-no-unknown */
|
|
@@ -13,8 +14,19 @@
|
|
|
13
14
|
/* stylelint-disable-next-line at-rule-no-unknown */
|
|
14
15
|
@tailwind utilities;
|
|
15
16
|
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
// 隐藏 label 的冒号
|
|
18
|
+
.ant-form-item .ant-form-item-label > label::after {
|
|
19
|
+
visibility: hidden;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.ant-modal-footer {
|
|
23
|
+
.ant-btn {
|
|
24
|
+
padding: 0 40px;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.ant-modal-confirm-btns {
|
|
29
|
+
.ant-btn {
|
|
30
|
+
padding: 0 40px;
|
|
31
|
+
}
|
|
20
32
|
}
|
|
@@ -22,7 +22,7 @@ type Story = StoryObj<typeof meta>;
|
|
|
22
22
|
export const Default: Story = {
|
|
23
23
|
args: {
|
|
24
24
|
title: '某某公司',
|
|
25
|
-
titleDescription: '某某公司的描述',
|
|
25
|
+
// titleDescription: '某某公司的描述',
|
|
26
26
|
enableSearch: true,
|
|
27
27
|
actions: ['create', 'update', 'delete'],
|
|
28
28
|
requestCreateByValues: (values) => {
|
package/src/tree/file_tree.tsx
CHANGED
|
@@ -79,6 +79,8 @@ function Detail<D extends DataNode>({
|
|
|
79
79
|
destroyOnHidden: true,
|
|
80
80
|
width: 400,
|
|
81
81
|
}}
|
|
82
|
+
layout="horizontal"
|
|
83
|
+
labelCol={{ span: 6 }}
|
|
82
84
|
>
|
|
83
85
|
<ProFormText name="key" hidden />
|
|
84
86
|
<ProFormText name="title" label="目录名称" required rules={[{ required: true }]} />
|
|
@@ -139,6 +141,7 @@ function More({
|
|
|
139
141
|
) : (
|
|
140
142
|
<OperateDelete
|
|
141
143
|
name={nodeData.title}
|
|
144
|
+
operateText="删除"
|
|
142
145
|
onDelete={() => requestDeleteByRecord?.({ key: nodeData.key })}
|
|
143
146
|
/>
|
|
144
147
|
),
|
package/src/tree/tree.tsx
CHANGED
|
@@ -187,9 +187,9 @@ function Tree<T extends DataNode>(props: TreeProps<T>) {
|
|
|
187
187
|
(enableSearch || title) && (
|
|
188
188
|
<div className="flex flex-col gap-2 py-2">
|
|
189
189
|
{(title || titleExtra) && (
|
|
190
|
-
<div className="flex gap-2
|
|
190
|
+
<div className="flex gap-2 p-2">
|
|
191
191
|
<div className="flex-1">
|
|
192
|
-
<div className="truncate">{title}</div>
|
|
192
|
+
<div className="truncate text-base">{title}</div>
|
|
193
193
|
{titleDescription && <div className="text-03">{titleDescription}</div>}
|
|
194
194
|
</div>
|
|
195
195
|
{titleExtra}
|