@fe-free/core 1.4.19 → 1.5.0

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,22 @@
1
1
  # @fe-free/core
2
2
 
3
+ ## 1.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - feat: form
8
+
9
+ ### Patch Changes
10
+
11
+ - @fe-free/tool@1.5.0
12
+
13
+ ## 1.4.20
14
+
15
+ ### Patch Changes
16
+
17
+ - feat: crud
18
+ - @fe-free/tool@1.4.20
19
+
3
20
  ## 1.4.19
4
21
 
5
22
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fe-free/core",
3
- "version": "1.4.19",
3
+ "version": "1.5.0",
4
4
  "description": "",
5
5
  "main": "./src/index.ts",
6
6
  "author": "",
@@ -36,7 +36,7 @@
36
36
  "react-syntax-highlighter": "^15.5.0",
37
37
  "vanilla-jsoneditor": "^0.23.1",
38
38
  "zustand": "^4.5.4",
39
- "@fe-free/tool": "1.4.19"
39
+ "@fe-free/tool": "1.5.0"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "@ant-design/pro-components": "^2.8.7",
@@ -1,10 +1,18 @@
1
1
  import { LoadingButton } from '@fe-free/core';
2
- import type { Meta, StoryObj } from '@storybook/react';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
3
 
4
4
  const meta: Meta<typeof LoadingButton> = {
5
5
  title: '@fe-free/core/LoadingButton',
6
6
  component: LoadingButton,
7
7
  tags: ['autodocs'],
8
+ parameters: {
9
+ docs: {
10
+ description: {
11
+ component:
12
+ 'LoadingButton 是一个带有加载状态的按钮组件,适用于异步操作场景。<br/>区别于 antd Button 需要手动传 loading props。',
13
+ },
14
+ },
15
+ },
8
16
  };
9
17
 
10
18
  export default meta;
@@ -1,7 +1,7 @@
1
1
  import type { ProColumns } from '@ant-design/pro-components';
2
2
  import { ProForm, ProFormSwitch, ProFormText } from '@ant-design/pro-components';
3
3
  import { CRUD, proFormSelectSearchProps } from '@fe-free/core';
4
- import type { Meta, StoryObj } from '@storybook/react';
4
+ import type { Meta, StoryObj } from '@storybook/react-vite';
5
5
  import { Button } from 'antd';
6
6
  import { useRef } from 'react';
7
7
  import {
@@ -500,3 +500,56 @@ export const RowSelection: Story = {
500
500
  );
501
501
  },
502
502
  };
503
+
504
+ export const ExpandedRowRender: Story = {
505
+ render: () => {
506
+ const columns = [
507
+ {
508
+ title: 'id',
509
+ dataIndex: 'id',
510
+ search: true,
511
+ },
512
+ {
513
+ title: '名字(省略)',
514
+ dataIndex: 'name',
515
+ search: true,
516
+ ellipsis: true,
517
+ },
518
+ ];
519
+
520
+ return (
521
+ <CRUD
522
+ actions={['create', 'read', 'delete', 'update']}
523
+ tableProps={{
524
+ columns,
525
+ request: fakeRequest,
526
+ defaultExpandAllRows: true,
527
+ expandable: {
528
+ expandedRowKeys: ['0', '1'],
529
+ expandedRowRender: () => {
530
+ return <div>123</div>;
531
+ },
532
+ },
533
+ }}
534
+ requestDeleteByRecord={fakeDeleteByRecord}
535
+ deleteProps={{
536
+ nameIndex: 'name',
537
+ }}
538
+ detailForm={() => (
539
+ <>
540
+ <ProFormText
541
+ name="name"
542
+ label="名字"
543
+ required
544
+ rules={[{ required: true }]}
545
+ extra="extra extra extra extra"
546
+ />
547
+ </>
548
+ )}
549
+ requestGetByRecord={fakeGetByRecord}
550
+ requestCreateByValues={fakeCreate}
551
+ requestUpdateById={fakeUpdateById}
552
+ />
553
+ );
554
+ },
555
+ };
package/src/crud/crud.tsx CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ActionType } from '@ant-design/pro-components';
2
- import { Button, message, Space } from 'antd';
2
+ import { Button, message } from 'antd';
3
3
  import { isString } from 'lodash-es';
4
4
  import { forwardRef, useCallback, useImperativeHandle, useMemo, useRef } from 'react';
5
5
  import { Link } from 'react-router-dom';
@@ -176,11 +176,11 @@ function CRUDComponent<
176
176
  }
177
177
 
178
178
  return (
179
- <Space>
179
+ <div className="fec-crud-operate-column flex gap-2">
180
180
  {operateColumnProps?.moreOperator && operateColumnProps.moreOperator(record)}
181
181
  {btns}
182
182
  {operateColumnProps?.moreOperatorAfter && operateColumnProps.moreOperatorAfter(record)}
183
- </Space>
183
+ </div>
184
184
  );
185
185
  },
186
186
  };
@@ -259,7 +259,7 @@ function CRUDComponent<
259
259
  });
260
260
 
261
261
  return (
262
- <div className="crud-table">
262
+ <div className="fec-crud">
263
263
  <Table<DataSource>
264
264
  rowKey="id"
265
265
  {...tableProps}
@@ -172,8 +172,8 @@ function CRUDDetail(props: CRUDDetailProps) {
172
172
 
173
173
  return (
174
174
  <div
175
- className={classNames('crud-detail', `crud-detail-action-${action}`, {
176
- 'crud-detail-hide-extra': action === 'read',
175
+ className={classNames('fec-crud-detail', `fec-crud-detail-action-${action}`, {
176
+ 'fec-crud-detail-hide-extra': action === 'read',
177
177
  })}
178
178
  >
179
179
  {detailForm({ readonly: action === 'read' && !!id }, { action })}
@@ -183,7 +183,7 @@ function CRUDDetail(props: CRUDDetailProps) {
183
183
 
184
184
  const drawerProps = useMemo(() => {
185
185
  return {
186
- destroyOnClose: true,
186
+ destroyOnHidden: true,
187
187
  };
188
188
  }, []);
189
189
 
@@ -1,6 +1,6 @@
1
1
  import { ProFormText } from '@ant-design/pro-components';
2
2
  import { CRUDOfSimple } from '@fe-free/core';
3
- import type { Meta, StoryObj } from '@storybook/react';
3
+ import type { Meta, StoryObj } from '@storybook/react-vite';
4
4
  import { fakeCreate, fakeDeleteByRecord, fakeRequest } from './demo/data';
5
5
 
6
6
  const meta: Meta<typeof CRUDOfSimple> = {
@@ -89,7 +89,7 @@ function CRUDOfSimpleComponent(props: CRUDOfSimpleProps, ref: React.ForwardedRef
89
89
  }, [debouncedSearchValue, simpleSearchProps, tableProps.params]);
90
90
 
91
91
  return (
92
- <div className="crud-of-simple">
92
+ <div className="fec-crud-of-simple">
93
93
  <CRUD
94
94
  ref={ref}
95
95
  {...rest}
@@ -1,6 +1,6 @@
1
- .crud-detail {
1
+ .fec-crud-detail {
2
2
  // 查看情况下隐藏 FormItem 的 extra
3
- &.crud-detail-hide-extra {
3
+ &.fec-crud-detail-hide-extra {
4
4
  .ant-form-item {
5
5
  .ant-form-item-extra {
6
6
  display: none;
@@ -9,7 +9,7 @@
9
9
  }
10
10
  }
11
11
 
12
- .crud-of-simple {
12
+ .fec-crud-of-simple {
13
13
  .ant-pro-table-list-toolbar {
14
14
  border-bottom: 1px solid #f0f0f0;
15
15
  }
@@ -1,6 +1,6 @@
1
1
  import type { EditorProps } from '@fe-free/core';
2
2
  import { Editor } from '@fe-free/core';
3
- import type { Meta, StoryObj } from '@storybook/react';
3
+ import type { Meta, StoryObj } from '@storybook/react-vite';
4
4
  import { useState } from 'react';
5
5
 
6
6
  const meta: Meta<typeof Editor> = {
@@ -1,5 +1,5 @@
1
1
  import { EditorJavascript } from '@fe-free/core';
2
- import type { Meta, StoryObj } from '@storybook/react';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
3
  import { useState } from 'react';
4
4
 
5
5
  const meta: Meta<typeof EditorJavascript> = {
@@ -1,5 +1,5 @@
1
1
  import { EditorJSON } from '@fe-free/core';
2
- import type { Meta, StoryObj } from '@storybook/react';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
3
  import { useState } from 'react';
4
4
 
5
5
  const meta: Meta<typeof EditorJSON> = {
@@ -1,5 +1,5 @@
1
1
  import { EditorLogs } from '@fe-free/core';
2
- import type { Meta, StoryObj } from '@storybook/react';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
3
 
4
4
  const meta: Meta<typeof EditorLogs> = {
5
5
  title: '@fe-free/core/EditorLogs',
@@ -1,5 +1,5 @@
1
1
  import { EditorMarkdown } from '@fe-free/core';
2
- import type { Meta, StoryObj } from '@storybook/react';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
3
  import { useState } from 'react';
4
4
 
5
5
  const meta: Meta<typeof EditorMarkdown> = {
@@ -1,15 +1,31 @@
1
1
  import { ProForm } from '@ant-design/pro-components';
2
- import { ProFormEditor, ProFormJSON, ProFormJavascript, ProFormSwitchNumber } from '@fe-free/core';
3
- import type { Meta, StoryObj } from '@storybook/react';
2
+ import {
3
+ ProFormEditor,
4
+ ProFormJSON,
5
+ ProFormJavascript,
6
+ ProFormListNumber,
7
+ ProFormListText,
8
+ ProFormSwitchNumber,
9
+ } from '@fe-free/core';
10
+ import type { Meta, StoryObj } from '@storybook/react-vite';
4
11
  import { useState } from 'react';
5
12
 
6
- const meta: Meta = {
13
+ const meta: Meta<typeof ProForm> = {
7
14
  title: '@fe-free/core/Form',
15
+ component: ProForm,
8
16
  tags: ['autodocs'],
17
+ parameters: {
18
+ docs: {
19
+ description: {
20
+ component:
21
+ 'Form 组件基于 Ant Design ProForm,支持多种表单类型和扩展字段,适用于复杂表单场景。',
22
+ },
23
+ },
24
+ },
9
25
  };
10
26
 
11
27
  export default meta;
12
- type Story = StoryObj<typeof meta>;
28
+ type Story = StoryObj<typeof ProForm>;
13
29
 
14
30
  function ProFormBase({
15
31
  children,
@@ -23,9 +39,11 @@ function ProFormBase({
23
39
  return (
24
40
  <ProForm
25
41
  initialValues={initialValues}
26
- onValuesChange={(values) => {
27
- console.log('values', values);
28
- setValues(values);
42
+ onValuesChange={(newValues) => {
43
+ setValues({
44
+ ...values,
45
+ ...newValues,
46
+ });
29
47
  }}
30
48
  onFinish={(values) => {
31
49
  console.log('values', values);
@@ -46,7 +64,7 @@ console.log('hello', name);
46
64
  `,
47
65
  }}
48
66
  >
49
- <ProFormEditor name="code" fieldProps={{ language: 'javascript', height: '50vh' }} />
67
+ <ProFormEditor name="code" fieldProps={{ language: 'javascript', height: '400px' }} />
50
68
  </ProFormBase>
51
69
  ),
52
70
  };
@@ -101,3 +119,20 @@ export const ProFormSwitchNumberComponent: Story = {
101
119
  </ProFormBase>
102
120
  ),
103
121
  };
122
+
123
+ export const ProFormListTextComponent: Story = {
124
+ render: () => (
125
+ <ProFormBase>
126
+ <ProFormListText name="listText" />
127
+ </ProFormBase>
128
+ ),
129
+ };
130
+
131
+ export const ProFormListNumberComponent: Story = {
132
+ render: () => (
133
+ <ProFormBase>
134
+ <ProFormListNumber name="listNumber" label="listNumber" />
135
+ <ProFormListNumber name="listInteger" label="listInteger" fieldProps={{ precision: 0 }} />
136
+ </ProFormBase>
137
+ ),
138
+ };
@@ -0,0 +1,127 @@
1
+ import type { ProFormItemProps } from '@ant-design/pro-components';
2
+ import { ProForm } from '@ant-design/pro-components';
3
+ import { Input, InputNumber } from 'antd';
4
+
5
+ import { ProFormListHelper } from './form_list_helper';
6
+
7
+ interface ListTextProps {
8
+ value?: (string | { value: string; label: string })[];
9
+ onChange?: (value: (string | { value: string; label: string })[]) => void;
10
+ isValueLabel?: boolean;
11
+ placeholder?: string;
12
+ }
13
+
14
+ function ListText(props: ListTextProps) {
15
+ const { isValueLabel, placeholder } = props;
16
+ return (
17
+ <ProFormListHelper value={props.value} onChange={props.onChange} getAdd={() => ''}>
18
+ {({ item, onItemChange }) => {
19
+ // @ts-ignore
20
+ const value = isValueLabel ? item.value : item;
21
+ return (
22
+ <Input
23
+ placeholder={placeholder}
24
+ value={value}
25
+ onChange={(e) => {
26
+ if (isValueLabel) {
27
+ onItemChange({ value: e.target.value, label: e.target.value });
28
+ } else {
29
+ onItemChange(e.target.value);
30
+ }
31
+ }}
32
+ />
33
+ );
34
+ }}
35
+ </ProFormListHelper>
36
+ );
37
+ }
38
+
39
+ interface ListNumberProps {
40
+ value?: (number | { value: number; label: string })[];
41
+ onChange?: (value: (number | { value: number; label: string })[]) => void;
42
+ isValueLabel?: boolean;
43
+ placeholder?: string;
44
+ precision?: number;
45
+ }
46
+
47
+ function ListNumber(props: ListNumberProps) {
48
+ const { isValueLabel, placeholder, precision } = props;
49
+ return (
50
+ <ProFormListHelper value={props.value} onChange={props.onChange} getAdd={() => 0}>
51
+ {({ item, onItemChange }) => {
52
+ // @ts-ignore
53
+ const value = isValueLabel ? item.value : item;
54
+ return (
55
+ <InputNumber
56
+ value={value}
57
+ onChange={(nv) => {
58
+ if (isValueLabel) {
59
+ onItemChange({ value: nv, label: nv.toString() });
60
+ } else {
61
+ onItemChange(nv);
62
+ }
63
+ }}
64
+ precision={precision}
65
+ style={{ width: '100%' }}
66
+ placeholder={placeholder}
67
+ />
68
+ );
69
+ }}
70
+ </ProFormListHelper>
71
+ );
72
+ }
73
+
74
+ function ProFormListBase(props) {
75
+ const { fieldProps, ...rest } = props;
76
+
77
+ const isValueLabel = fieldProps?.isValueLabel;
78
+
79
+ return (
80
+ <ProForm.Item
81
+ {...rest}
82
+ required={props.required ?? true}
83
+ rules={[
84
+ ...(props.rules || []),
85
+ // { required: true },
86
+ {
87
+ validator: async (_, value) => {
88
+ if (isValueLabel) {
89
+ if (value?.some((item) => item.value === undefined)) {
90
+ return Promise.reject('每个选项都不能为空');
91
+ }
92
+ } else {
93
+ if (value?.some((item) => item === undefined)) {
94
+ return Promise.reject('每个选项都不能为空');
95
+ }
96
+ }
97
+ return Promise.resolve();
98
+ },
99
+ },
100
+ ]}
101
+ >
102
+ {props.children}
103
+ </ProForm.Item>
104
+ );
105
+ }
106
+
107
+ function ProFormListText(props: ProFormItemProps<ListTextProps>) {
108
+ const { fieldProps, ...rest } = props;
109
+
110
+ return (
111
+ <ProFormListBase {...rest}>
112
+ <ListText {...fieldProps} />
113
+ </ProFormListBase>
114
+ );
115
+ }
116
+
117
+ function ProFormListNumber(props: ProFormItemProps<ListNumberProps>) {
118
+ const { fieldProps, ...rest } = props;
119
+
120
+ return (
121
+ <ProFormListBase {...rest}>
122
+ <ListNumber {...fieldProps} />
123
+ </ProFormListBase>
124
+ );
125
+ }
126
+
127
+ export { ProFormListNumber, ProFormListText };
@@ -0,0 +1,74 @@
1
+ import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
2
+ import { Button } from 'antd';
3
+
4
+ interface ProFormListHelperProps<T> {
5
+ value?: T[];
6
+ onChange?: (value: T[]) => void;
7
+ children: (props: {
8
+ value?: T[];
9
+ item: T;
10
+ index: number;
11
+ onItemChange: (newItem: T) => void;
12
+ }) => React.ReactNode;
13
+ addText?: string;
14
+ getAdd: () => T;
15
+ readOnly?: boolean;
16
+ }
17
+
18
+ const emptyArr = [];
19
+ function ProFormListHelper<T = any>(props: ProFormListHelperProps<T>) {
20
+ const options = props.value || emptyArr;
21
+
22
+ return (
23
+ <div className="flex flex-col gap-2">
24
+ <div className="flex flex-col gap-2">
25
+ {options.map((item, index) => {
26
+ return (
27
+ <div key={index} className="flex">
28
+ <div className="flex-1 overflow-hidden">
29
+ {props.children({
30
+ value: props.value,
31
+ item,
32
+ index,
33
+ onItemChange: (newItem) => {
34
+ const newOptions = [...options];
35
+ newOptions[index] = newItem;
36
+ props.onChange?.(newOptions);
37
+ },
38
+ })}
39
+ </div>
40
+ {!props.readOnly && (
41
+ <Button
42
+ icon={<DeleteOutlined />}
43
+ type="text"
44
+ onClick={() => {
45
+ const newOptions = [...options];
46
+ newOptions.splice(index, 1);
47
+ props.onChange?.(newOptions);
48
+ }}
49
+ />
50
+ )}
51
+ </div>
52
+ );
53
+ })}
54
+ </div>
55
+ {!props.readOnly && (
56
+ <div className="flex justify-center">
57
+ <Button
58
+ size="small"
59
+ icon={<PlusOutlined />}
60
+ onClick={() => {
61
+ const newOptions = [...options];
62
+ newOptions.push(props.getAdd());
63
+ props.onChange?.(newOptions);
64
+ }}
65
+ >
66
+ {props.addText || '添加'}
67
+ </Button>
68
+ </div>
69
+ )}
70
+ </div>
71
+ );
72
+ }
73
+
74
+ export { ProFormListHelper };
@@ -0,0 +1,147 @@
1
+ import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons';
2
+ import { ModalForm } from '@ant-design/pro-components';
3
+ import { Button } from 'antd';
4
+ import React from 'react';
5
+
6
+ const emptyArr = [];
7
+
8
+ function Edit<T>(props: {
9
+ children: JSX.Element;
10
+ values?: T;
11
+ onChange: (values: T) => void;
12
+ detailForm: JSX.Element;
13
+ editForm?: any;
14
+ disabledAddFormSubmitter?: boolean;
15
+ }) {
16
+ const handleFinish = async (newValues) => {
17
+ props.onChange(newValues as T);
18
+
19
+ return true;
20
+ };
21
+
22
+ return (
23
+ <ModalForm
24
+ title={props.values ? '编辑' : '添加'}
25
+ trigger={props.children}
26
+ onFinish={handleFinish}
27
+ formRef={props?.editForm}
28
+ initialValues={props.values || undefined}
29
+ submitter={
30
+ props.disabledAddFormSubmitter
31
+ ? false
32
+ : {
33
+ render: (props, defaultDoms) => {
34
+ return [
35
+ <div
36
+ key="cancel"
37
+ className="pr-[20px] w-[500px] pt-[12px]"
38
+ style={{ borderTop: '1px solid rgba(0, 0, 0, 0.1)' }}
39
+ >
40
+ <div className="custom-button-container">
41
+ {React.Children.map(defaultDoms, (dom) => {
42
+ return React.cloneElement(dom, {
43
+ className:
44
+ 'w-[88px] h-[40px] text-base rounded-[0.5rem] ml-3' +
45
+ (dom.props?.className || ''),
46
+ });
47
+ })}
48
+ </div>
49
+ </div>,
50
+ ];
51
+ },
52
+ }
53
+ }
54
+ >
55
+ {props.detailForm}
56
+ </ModalForm>
57
+ );
58
+ }
59
+
60
+ interface ProFormListModalHelperProps<T> {
61
+ value?: T[];
62
+ onChange?: (value: T[]) => void;
63
+ children: (props: { value?: T[]; item: T; index: number }) => React.ReactNode;
64
+ readOnly?: boolean;
65
+ detailForm: JSX.Element;
66
+ // 如果 addForm 存在,则使用 addForm 作为添加按钮
67
+ addForm?: JSX.Element;
68
+ // 禁用添加的提交按钮
69
+ disabledAddFormSubmitter?: boolean;
70
+
71
+ disabledAdd?: boolean;
72
+ // 触发添加
73
+ addTrigger?: JSX.Element;
74
+
75
+ editForm?: any;
76
+ }
77
+
78
+ function ProFormListModalHelper<T = any>(props: ProFormListModalHelperProps<T>) {
79
+ const options = props.value || emptyArr;
80
+
81
+ return (
82
+ <div className="flex flex-col gap-2">
83
+ <div className="flex flex-col gap-2">
84
+ {options.map((item, index) => {
85
+ return (
86
+ <div key={index} className="group relative">
87
+ <div className="flex-1">
88
+ {props.children({
89
+ value: props.value,
90
+ item,
91
+ index,
92
+ })}
93
+ </div>
94
+ {!props.readOnly && (
95
+ <div className="absolute right-1 top-1 hidden items-center bg-white group-hover:flex">
96
+ <Edit<T>
97
+ values={item}
98
+ onChange={(newValues) => {
99
+ const newOptions = [...options];
100
+ newOptions[index] = newValues;
101
+ props.onChange?.(newOptions);
102
+ }}
103
+ detailForm={props.detailForm}
104
+ editForm={props?.editForm}
105
+ >
106
+ <Button icon={<EditOutlined />} type="text" size="small" />
107
+ </Edit>
108
+ <Button
109
+ icon={<DeleteOutlined />}
110
+ type="text"
111
+ size="small"
112
+ onClick={() => {
113
+ const newOptions = [...options];
114
+ newOptions.splice(index, 1);
115
+ props.onChange?.(newOptions);
116
+ }}
117
+ />
118
+ </div>
119
+ )}
120
+ </div>
121
+ );
122
+ })}
123
+ </div>
124
+ {!props.readOnly && !props.disabledAdd && (
125
+ <div className="flex justify-center">
126
+ <Edit<T>
127
+ onChange={(newValues) => {
128
+ props.onChange?.([...options, newValues]);
129
+ }}
130
+ detailForm={props.addForm || props.detailForm}
131
+ editForm={props?.editForm}
132
+ disabledAddFormSubmitter={props.disabledAddFormSubmitter}
133
+ >
134
+ {props.addTrigger || (
135
+ <Button size="small" icon={<PlusOutlined />}>
136
+ 添加
137
+ </Button>
138
+ )}
139
+ </Edit>
140
+ </div>
141
+ )}
142
+ </div>
143
+ );
144
+ }
145
+
146
+ export { ProFormListModalHelper };
147
+ export type { ProFormListModalHelperProps };
@@ -1,3 +1,7 @@
1
+ export { ProFormListNumber, ProFormListText } from './form_list/form_list';
2
+ export { ProFormListHelper } from './form_list/form_list_helper';
3
+ export { ProFormListModalHelper } from './form_list/form_list_modal_helper';
4
+
1
5
  export { ProFormEditor } from './pro_form_editor';
2
6
  export { ProFormJavascript } from './pro_form_javascript';
3
7
  export { ProFormJSON } from './pro_form_json';
@@ -8,12 +8,11 @@ function EditorItem(props: EditorProps) {
8
8
  }
9
9
 
10
10
  function ProFormEditor(props: ProFormItemProps<EditorProps>) {
11
- /* eslint-disable-next-line */
12
- const { fieldProps, readonly, ...rest } = props;
11
+ const { fieldProps, ...rest } = props;
13
12
 
14
13
  return (
15
14
  <ProForm.Item {...rest}>
16
- <EditorItem readOnly={readonly} {...(fieldProps as EditorProps)} />
15
+ <EditorItem {...fieldProps} />
17
16
  </ProForm.Item>
18
17
  );
19
18
  }
@@ -12,12 +12,11 @@ function JavascriptItem(props: EditorJavascriptProps) {
12
12
  }
13
13
 
14
14
  function ProFormJavascript(props: ProFormItemProps<EditorJavascriptProps>) {
15
- /* eslint-disable-next-line */
16
- const { fieldProps, readonly, ...rest } = props;
15
+ const { fieldProps, ...rest } = props;
17
16
 
18
17
  return (
19
18
  <ProForm.Item {...rest}>
20
- <JavascriptItem readonly={readonly} {...(fieldProps as EditorJavascriptProps)} />
19
+ <JavascriptItem {...(fieldProps as EditorJavascriptProps)} />
21
20
  </ProForm.Item>
22
21
  );
23
22
  }
@@ -12,12 +12,11 @@ function JSONItem(props: EditorJSONProps) {
12
12
  }
13
13
 
14
14
  function ProFormJSON(props: ProFormItemProps<EditorJSONProps>) {
15
- /* eslint-disable-next-line */
16
- const { fieldProps, readonly, ...rest } = props;
15
+ const { fieldProps, ...rest } = props;
17
16
 
18
17
  return (
19
18
  <ProForm.Item {...rest}>
20
- <JSONItem readonly={props.readonly} {...(fieldProps as EditorJSONProps)} />
19
+ <JSONItem {...(fieldProps as EditorJSONProps)} />
21
20
  </ProForm.Item>
22
21
  );
23
22
  }
@@ -25,8 +25,7 @@ function SwitchNumber(props: SwitchNumberProps) {
25
25
  }
26
26
 
27
27
  function ProFormSwitchNumber(props: ProFormItemProps<SwitchNumberProps>) {
28
- /* eslint-disable-next-line */
29
- const { fieldProps, readonly, ...rest } = props;
28
+ const { fieldProps, ...rest } = props;
30
29
 
31
30
  return (
32
31
  <ProForm.Item {...rest}>
package/src/index.ts CHANGED
@@ -21,6 +21,10 @@ export {
21
21
  ProFormEditor,
22
22
  ProFormJSON,
23
23
  ProFormJavascript,
24
+ ProFormListHelper,
25
+ ProFormListModalHelper,
26
+ ProFormListNumber,
27
+ ProFormListText,
24
28
  ProFormSwitchNumber,
25
29
  proFormSelectSearchProps,
26
30
  } from './form';
@@ -47,11 +47,15 @@ function Table<
47
47
  columns={newColumns}
48
48
  scroll={getTableScroll(newColumns)}
49
49
  search={
50
- hasSearch && {
51
- labelWidth: 'auto',
52
- defaultCollapsed: false,
53
- ...search,
54
- }
50
+ hasSearch
51
+ ? {
52
+ labelWidth: 'auto',
53
+ defaultCollapsed: false,
54
+ ...search,
55
+ }
56
+ : {
57
+ ...search,
58
+ }
55
59
  }
56
60
  {...rest}
57
61
  />
@@ -1,15 +1,28 @@
1
1
  import type { ProColumns } from '@ant-design/pro-components';
2
2
  import { Table } from '@fe-free/core';
3
- import type { Meta, StoryObj } from '@storybook/react';
3
+ import type { Meta, StoryObj } from '@storybook/react-vite';
4
4
  import { fakeData } from '../crud/demo/data';
5
5
 
6
- const meta: Meta = {
6
+ const meta: Meta<typeof Table> = {
7
7
  title: '@fe-free/core/Table',
8
+ component: Table,
8
9
  tags: ['autodocs'],
10
+ parameters: {
11
+ docs: {
12
+ description: {
13
+ component: `Table 基于 ProTable 做了一些封装:<br>
14
+ - props column 需要显示的提供 search: true;
15
+ - 列宽默认 120,和滚动条
16
+ - 搜索样式做了默认设置,具体见代码
17
+ - 页码做了默认设置,具体见代码
18
+ `,
19
+ },
20
+ },
21
+ },
9
22
  };
10
23
 
11
24
  export default meta;
12
- type Story = StoryObj<typeof meta>;
25
+ type Story = StoryObj<typeof Table>;
13
26
 
14
27
  // 定义列配置
15
28
  const columns: ProColumns[] = [
@@ -51,30 +64,32 @@ export const Basic: Story = {
51
64
  ),
52
65
  };
53
66
 
54
- export const Search: Story = {
67
+ export const ScrollX: Story = {
55
68
  render: () => (
56
- <Table
57
- columns={[
58
- {
59
- title: 'id',
60
- dataIndex: 'id',
61
- },
62
- {
63
- title: '名字(省略)',
64
- dataIndex: 'name',
69
+ <div className="w-[400px]">
70
+ <Table
71
+ rowKey="id"
72
+ columns={[
73
+ {
74
+ title: 'id',
75
+ dataIndex: 'id',
76
+ },
77
+ {
78
+ title: '名字(省略)',
79
+ dataIndex: 'name',
65
80
 
66
- ellipsis: true,
67
- },
68
- {
69
- title: 'city',
70
- dataIndex: 'city',
71
- },
72
- {
73
- title: 'area',
74
- dataIndex: 'area',
75
- },
76
- ]}
77
- rowKey="id"
78
- />
81
+ ellipsis: true,
82
+ },
83
+ {
84
+ title: 'city',
85
+ dataIndex: 'city',
86
+ },
87
+ {
88
+ title: 'area',
89
+ dataIndex: 'area',
90
+ },
91
+ ]}
92
+ />
93
+ </div>
79
94
  ),
80
95
  };
@@ -1,6 +1,6 @@
1
1
  import { ProConfigProvider } from '@ant-design/pro-components';
2
2
  import { CRUD, CustomValueTypeEnum, customValueTypeMap } from '@fe-free/core';
3
- import type { Meta, StoryObj } from '@storybook/react';
3
+ import type { Meta, StoryObj } from '@storybook/react-vite';
4
4
  import dayjs from 'dayjs';
5
5
  import { range } from 'lodash-es';
6
6