@fe-free/core 1.4.20 → 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,15 @@
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
+
3
13
  ## 1.4.20
4
14
 
5
15
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fe-free/core",
3
- "version": "1.4.20",
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.20"
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
+ };
@@ -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> = {
@@ -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