@fe-free/core 3.0.8 → 3.0.10

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.10
4
+
5
+ ### Patch Changes
6
+
7
+ - feat: ui
8
+ - @fe-free/tool@3.0.10
9
+
10
+ ## 3.0.9
11
+
12
+ ### Patch Changes
13
+
14
+ - fix: crud
15
+ - @fe-free/tool@3.0.9
16
+
3
17
  ## 3.0.8
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.8",
3
+ "version": "3.0.10",
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.8"
44
+ "@fe-free/tool": "3.0.10"
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<any>();
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.getActionRef().current?.reload()}>reload</Button>
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 { forwardRef, useCallback, useImperativeHandle, useMemo, useRef } from 'react';
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 { CRUDMethods, CRUDProps } from './types';
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 CRUDComponent<
18
- DataSource extends Record<string, any> = any,
19
- Key extends string | number = string,
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 };
@@ -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 { CRUDMethods, CRUDProps } from './types';
5
+ export type { CRUDProps, CRUDRef } from './types';
@@ -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: React.MouseEvent<HTMLElement>,
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
- interface CRUDMethods {
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
- <CRUDOfList
49
- actions={[]}
50
- tableProps={{
51
- columns,
52
- request: fakeRequest,
53
- }}
54
- requestDeleteByRecord={fakeDeleteByRecord}
55
- deleteProps={{
56
- nameIndex: 'name',
57
- }}
58
- detailForm={() => (
59
- <>
60
- <ProFormText name="name" label="名字" required rules={[{ required: true }]} />
61
- </>
62
- )}
63
- requestCreateByValues={fakeCreate}
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 { forwardRef, useCallback, useEffect, useMemo, useState } from 'react';
5
- import type { CRUDMethods, CRUDProps } from '../crud';
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 CRUDOfListComponent(props: CRUDOfListProps, ref: React.ForwardedRef<CRUDMethods>) {
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 };
@@ -340,8 +340,7 @@ export const FullPage: Story = {
340
340
  <div className="h-[800px] border border-red-500">
341
341
  <CRUDOfPure
342
342
  fullPage
343
- specialSearch
344
- // specialToolbar
343
+ specialToolbar
345
344
  actions={['create', 'delete']}
346
345
  tableProps={{
347
346
  columns,
@@ -1,6 +1,6 @@
1
1
  import classNames from 'classnames';
2
- import { forwardRef, useMemo } from 'react';
3
- import type { CRUDMethods, CRUDProps } from '../crud';
2
+ import { useMemo } from 'react';
3
+ import type { CRUDProps } from '../crud';
4
4
  import { CRUD } from '../crud';
5
5
  import './style.scss';
6
6
 
@@ -9,12 +9,11 @@ interface CRUDOfPureProps<
9
9
  DataSource extends Record<string, any> = any,
10
10
  Key extends string | number = string,
11
11
  > extends CRUDProps<DataSource, Key> {
12
- specialSearch?: boolean;
13
12
  /** 特殊位置的 toolbar,向上 margin,是的 search 和 toolbar 一起。仅适用于 search 很少的情况。 */
14
13
  specialToolbar?: boolean;
15
14
  }
16
15
 
17
- function CRUDOfPureComponent(props: CRUDOfPureProps, ref: React.ForwardedRef<CRUDMethods>) {
16
+ function CRUDOfPure(props: CRUDOfPureProps) {
18
17
  const newColumns = props.tableProps.columns?.map((column) => {
19
18
  if (column.search) {
20
19
  return {
@@ -41,13 +40,11 @@ function CRUDOfPureComponent(props: CRUDOfPureProps, ref: React.ForwardedRef<CRU
41
40
 
42
41
  return (
43
42
  <CRUD
44
- ref={ref}
45
43
  {...props}
46
44
  className={classNames(
47
45
  'fec-crud-of-pure',
48
46
  {
49
47
  'fec-crud-of-pure-no-search': noSearch,
50
- 'fec-crud-of-pure-special-search': props.specialSearch,
51
48
  'fec-crud-of-pure-special-toolbar': props.specialToolbar,
52
49
  },
53
50
  props.className,
@@ -69,12 +66,5 @@ function CRUDOfPureComponent(props: CRUDOfPureProps, ref: React.ForwardedRef<CRU
69
66
  );
70
67
  }
71
68
 
72
- const CRUDOfPure = forwardRef(CRUDOfPureComponent) as <
73
- DataSource extends Record<string, any> = any,
74
- Key extends string | number = string,
75
- >(
76
- props: CRUDOfPureProps<DataSource, Key> & { ref?: React.ForwardedRef<CRUDMethods> },
77
- ) => JSX.Element;
78
-
79
69
  export { CRUDOfPure };
80
70
  export type { CRUDOfPureProps };
@@ -49,22 +49,17 @@
49
49
  }
50
50
  }
51
51
 
52
- &.fec-crud-of-pure-special-search {
52
+ &.fec-crud-of-pure-special-toolbar {
53
53
  .ant-pro-table-search {
54
- position: absolute;
55
- z-index: 1;
56
- background: transparent;
57
- width: auto;
54
+ z-index: 10;
58
55
  }
59
56
 
60
- .ant-pro-table-list-toolbar-container {
61
- padding-block-start: 16px;
57
+ .ant-pro-card:not(.ant-pro-table-search) {
58
+ margin-top: -48px;
62
59
  }
63
- }
64
60
 
65
- &.fec-crud-of-pure-special-toolbar {
66
61
  .ant-pro-table-list-toolbar {
67
- margin-top: -48px;
62
+ z-index: 10;
68
63
  pointer-events: none;
69
64
 
70
65
  .ant-pro-table-list-toolbar-right > div {
@@ -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
- <div key={item.key} className="flex gap-2">
22
- <FileCard name={`这是文件名.${item.ext.join('.') || ''}`} size={(size += 1000000)} />
23
- </div>
21
+ <FileCard
22
+ key={item.key}
23
+ name={`这是文件名.${item.ext.join('.') || ''}`}
24
+ size={(size += 1000000)}
25
+ />
24
26
  ))}
25
27
  </div>
26
28
  </div>
@@ -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-4xl" />
58
- <div className={classNames('flex flex-col', { 'items-center': direction === 'vertical' })}>
59
- {name && <div className="truncate">{name}</div>}
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, CRUDMethods, CRUDProps } from './crud';
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
@@ -13,8 +13,19 @@
13
13
  /* stylelint-disable-next-line at-rule-no-unknown */
14
14
  @tailwind utilities;
15
15
 
16
- // fix
17
- // ant-pro-card-border 有个 transition 导致颜色会变化,所以就写死个。
18
- .ant-pro-card-border {
19
- border: 1px solid #e2e7f0;
16
+ // 隐藏 label 的冒号
17
+ .ant-form-item .ant-form-item-label > label::after {
18
+ visibility: hidden;
19
+ }
20
+
21
+ .ant-modal-footer {
22
+ .ant-btn {
23
+ padding: 0 40px;
24
+ }
25
+ }
26
+
27
+ .ant-modal-confirm-btns {
28
+ .ant-btn {
29
+ padding: 0 40px;
30
+ }
20
31
  }
@@ -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) => {
@@ -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 px-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}