antd-hooks 1.0.1 → 1.0.2

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.
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ interface ModalInstance {
3
+ destroy: () => void;
4
+ update: (props: any) => void;
5
+ }
6
+ declare const useModal: <T extends Record<string, any> = {}>(ModalComponent: React.ComponentType<any>) => (props?: T) => ModalInstance;
7
+ export default useModal;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ interface ModalInstance {
3
+ destroy: () => void;
4
+ update: (props: any) => void;
5
+ }
6
+ declare const useModal: <T extends Record<string, any> = {}>(ModalComponent: React.ComponentType<any>) => (props?: T) => ModalInstance;
7
+ export default useModal;
@@ -0,0 +1,49 @@
1
+ import type { TableProps, PaginationProps, InputProps } from 'antd';
2
+ interface ResponseData<T = any> {
3
+ list: T[];
4
+ total: number;
5
+ current?: number;
6
+ pageSize?: number;
7
+ }
8
+ interface FilterConfig {
9
+ dataIndex: string;
10
+ placeholder?: string;
11
+ debounce?: number;
12
+ }
13
+ interface FieldMapping {
14
+ list?: string;
15
+ total?: string;
16
+ current?: string;
17
+ pageSize?: string;
18
+ }
19
+ interface UseDataTableOptions<T = any> {
20
+ url?: string;
21
+ data?: T[];
22
+ params?: Record<string, any>;
23
+ columns: TableProps<T>['columns'];
24
+ rowKey?: string | ((record: T) => string);
25
+ immediate?: boolean;
26
+ transformData?: (data: any) => ResponseData<T>;
27
+ fieldMapping?: FieldMapping;
28
+ filter?: FilterConfig;
29
+ pagination?: boolean | PaginationProps;
30
+ request?: (params: any) => Promise<any>;
31
+ }
32
+ interface UseDataTableReturn<T = any> {
33
+ tableProps: TableProps<T>;
34
+ data: T[];
35
+ loading: boolean;
36
+ total: number;
37
+ paginationProps: PaginationProps;
38
+ current: number;
39
+ pageSize: number;
40
+ filterProps: InputProps;
41
+ filterValue: string;
42
+ refresh: () => void;
43
+ search: (params: Record<string, any>) => void;
44
+ reset: () => void;
45
+ setData: (data: T[]) => void;
46
+ setLoading: (loading: boolean) => void;
47
+ }
48
+ declare const useDataTable: <T = any>(options: UseDataTableOptions<T>) => UseDataTableReturn<T>;
49
+ export default useDataTable;
@@ -0,0 +1 @@
1
+ import"react";import"react-dom";"function"==typeof SuppressedError&&SuppressedError;
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";require("react"),require("react-dom"),"function"==typeof SuppressedError&&SuppressedError;
package/package.json CHANGED
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "name": "antd-hooks",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "A collection of enhanced hooks for Ant Design",
5
- "main": "index.js",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.esm.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
6
11
  "scripts": {
7
12
  "build": "rollup -c --bundleConfigAsCjs",
8
13
  "dev": "rollup -c -w",
package/rollup.config.mjs DELETED
@@ -1,30 +0,0 @@
1
- import typescript from '@rollup/plugin-typescript';
2
- import { nodeResolve } from '@rollup/plugin-node-resolve';
3
- import commonjs from '@rollup/plugin-commonjs';
4
- import { terser } from 'rollup-plugin-terser';
5
-
6
- export default {
7
- input: 'src/index.ts',
8
- output: [
9
- {
10
- file: 'dist/index.js',
11
- format: 'cjs',
12
- exports: 'named'
13
- },
14
- {
15
- file: 'dist/index.esm.js',
16
- format: 'esm'
17
- }
18
- ],
19
- plugins: [
20
- nodeResolve(),
21
- commonjs(),
22
- typescript({
23
- declaration: true,
24
- declarationDir: 'dist',
25
- exclude: ['**/*.test.*', '**/*.spec.*']
26
- }),
27
- terser()
28
- ],
29
- external: ['react', 'react-dom', 'antd']
30
- };
@@ -1,57 +0,0 @@
1
- import React, { createElement } from 'react';
2
- import ReactDOM from 'react-dom';
3
-
4
- interface ModalInstance {
5
- destroy: () => void;
6
- update: (props: any) => void;
7
- }
8
-
9
- const useModal = <T extends Record<string, any> = {}>(
10
- ModalComponent: React.ComponentType<any>
11
- ) => {
12
- const showModal = (props?: T): ModalInstance => {
13
- const container = document.createElement('div');
14
- document.body.appendChild(container);
15
-
16
- let currentProps = { ...props, open: true };
17
-
18
- const destroy = () => {
19
- ReactDOM.unmountComponentAtNode(container);
20
- if (container.parentNode) {
21
- container.parentNode.removeChild(container);
22
- }
23
- };
24
-
25
- const update = (newProps: any) => {
26
- currentProps = { ...currentProps, ...newProps };
27
- render(currentProps);
28
- };
29
-
30
- const render = (props: any) => {
31
- const element = createElement(ModalComponent, {
32
- ...props,
33
- onCancel: (...args: any[]) => {
34
- props.onCancel?.(...args);
35
- destroy();
36
- },
37
- onOk: (...args: any[]) => {
38
- props.onOk?.(...args);
39
- destroy();
40
- },
41
- afterClose: destroy,
42
- });
43
- ReactDOM.render(element, container);
44
- };
45
-
46
- render(currentProps);
47
-
48
- return {
49
- destroy,
50
- update,
51
- };
52
- };
53
-
54
- return showModal;
55
- };
56
-
57
- export default useModal;
@@ -1,406 +0,0 @@
1
- import { useState, useEffect, useCallback, useMemo } from 'react';
2
- import type { TableProps, PaginationProps, InputProps } from 'antd';
3
-
4
- // 类型定义
5
- interface RequestParams {
6
- current: number;
7
- pageSize: number;
8
- [key: string]: any;
9
- }
10
-
11
- interface ResponseData<T = any> {
12
- list: T[];
13
- total: number;
14
- current?: number;
15
- pageSize?: number;
16
- }
17
-
18
- interface FilterConfig {
19
- dataIndex: string;
20
- placeholder?: string;
21
- debounce?: number;
22
- }
23
-
24
- interface FieldMapping {
25
- list?: string;
26
- total?: string;
27
- current?: string;
28
- pageSize?: string;
29
- }
30
-
31
- interface UseDataTableOptions<T = any> {
32
- // 数据源配置
33
- url?: string;
34
- data?: T[]; // 静态数据源
35
- params?: Record<string, any>;
36
-
37
- // 表格配置
38
- columns: TableProps<T>['columns'];
39
- rowKey?: string | ((record: T) => string);
40
- immediate?: boolean;
41
-
42
- // 数据转换
43
- transformData?: (data: any) => ResponseData<T>;
44
- fieldMapping?: FieldMapping;
45
-
46
- // 筛选配置
47
- filter?: FilterConfig;
48
-
49
- // 分页配置
50
- pagination?: boolean | PaginationProps;
51
-
52
- // 请求配置
53
- request?: (params: any) => Promise<any>;
54
- }
55
-
56
- interface UseDataTableReturn<T = any> {
57
- // 核心属性
58
- tableProps: TableProps<T>;
59
- data: T[];
60
- loading: boolean;
61
- total: number;
62
-
63
- // 分页相关
64
- paginationProps: PaginationProps;
65
- current: number;
66
- pageSize: number;
67
-
68
- // 筛选相关
69
- filterProps: InputProps;
70
- filterValue: string;
71
-
72
- // 操作方法
73
- refresh: () => void;
74
- search: (params: Record<string, any>) => void;
75
- reset: () => void;
76
- setData: (data: T[]) => void;
77
- setLoading: (loading: boolean) => void;
78
- }
79
-
80
- // 工具函数:获取嵌套对象属性值
81
- const getNestedValue = (obj: any, path: string): any => {
82
- if (!path) return undefined;
83
- return path.split('.').reduce((acc, part) => acc && acc[part], obj);
84
- };
85
-
86
- // 主 Hook 实现
87
- const useDataTable = <T = any>(options: UseDataTableOptions<T>): UseDataTableReturn<T> => {
88
- const {
89
- // 数据源
90
- url,
91
- data: staticData,
92
- params: initialParams = {},
93
-
94
- // 表格配置
95
- columns,
96
- rowKey = 'id',
97
- immediate = true,
98
-
99
- // 数据转换
100
- transformData,
101
- fieldMapping = {
102
- list: 'list',
103
- total: 'total',
104
- current: 'current',
105
- pageSize: 'pageSize',
106
- },
107
-
108
- // 筛选配置
109
- filter,
110
-
111
- // 分页配置
112
- pagination: paginationConfig = true,
113
-
114
- // 自定义请求
115
- request,
116
- } = options;
117
-
118
- // 状态管理
119
- const [data, setData] = useState<T[]>([]);
120
- const [loading, setLoading] = useState(false);
121
- const [total, setTotal] = useState(0);
122
- const [pagination, setPagination] = useState({
123
- current: 1,
124
- pageSize: 10,
125
- });
126
- const [searchParams, setSearchParams] = useState<Record<string, any>>(initialParams);
127
- const [filterValue, setFilterValue] = useState('');
128
- const [filteredData, setFilteredData] = useState<T[]>([]);
129
- const [debounceTimer, setDebounceTimer] = useState<NodeJS.Timeout | null>(null);
130
-
131
- // 判断是否使用静态数据
132
- const isStaticData = !!staticData;
133
-
134
- // 获取表格数据
135
- const fetchData = useCallback(async () => {
136
- if (isStaticData) {
137
- // 使用静态数据
138
- setData(staticData);
139
- setTotal(staticData.length);
140
- return;
141
- }
142
-
143
- if (!url && !request) {
144
- console.warn('useDataTable: 请提供 url 或 request 参数');
145
- return;
146
- }
147
-
148
- setLoading(true);
149
- try {
150
- const requestParams: RequestParams = {
151
- current: pagination.current,
152
- pageSize: pagination.pageSize,
153
- ...searchParams,
154
- };
155
-
156
- let result;
157
- if (request) {
158
- // 使用自定义请求方法
159
- result = await request(requestParams);
160
- } else if (url) {
161
- // 使用默认 fetch
162
- const response = await fetch(url, {
163
- method: 'POST',
164
- headers: {
165
- 'Content-Type': 'application/json',
166
- },
167
- body: JSON.stringify(requestParams),
168
- });
169
- result = await response.json();
170
- }
171
-
172
- // 数据提取和转换
173
- let finalData: ResponseData<T>;
174
- if (transformData) {
175
- finalData = transformData(result);
176
- } else {
177
- const listData = getNestedValue(result, fieldMapping.list!) || [];
178
- const totalCount = getNestedValue(result, fieldMapping.total!) || 0;
179
- const currentPage = getNestedValue(result, fieldMapping.current!);
180
- const pageSizeValue = getNestedValue(result, fieldMapping.pageSize!);
181
-
182
- finalData = {
183
- list: listData,
184
- total: totalCount,
185
- current: currentPage,
186
- pageSize: pageSizeValue,
187
- };
188
- }
189
-
190
- setData(finalData.list || []);
191
- setTotal(finalData.total || 0);
192
-
193
- // 更新分页信息
194
- if (finalData.current) {
195
- setPagination(prev => ({
196
- ...prev,
197
- current: finalData.current!,
198
- }));
199
- }
200
- if (finalData.pageSize) {
201
- setPagination(prev => ({
202
- ...prev,
203
- pageSize: finalData.pageSize!,
204
- }));
205
- }
206
- } catch (error) {
207
- console.error('表格数据请求失败:', error);
208
- setData([]);
209
- setTotal(0);
210
- } finally {
211
- setLoading(false);
212
- }
213
- }, [
214
- url,
215
- staticData,
216
- isStaticData,
217
- pagination.current,
218
- pagination.pageSize,
219
- searchParams,
220
- transformData,
221
- fieldMapping.list,
222
- fieldMapping.total,
223
- fieldMapping.current,
224
- fieldMapping.pageSize,
225
- request,
226
- ]);
227
-
228
- // 筛选数据
229
- useEffect(() => {
230
- if (!filterValue || !filter) {
231
- setFilteredData(data);
232
- return;
233
- }
234
-
235
- const filtered = data.filter(item => {
236
- const fieldValue = getNestedValue(item, filter.dataIndex);
237
- return String(fieldValue || '').toLowerCase().includes(filterValue.toLowerCase());
238
- });
239
-
240
- setFilteredData(filtered);
241
- }, [data, filterValue, filter]);
242
-
243
- // 处理筛选变化(防抖)
244
- const handleFilterChange = useCallback((value: string) => {
245
- setFilterValue(value);
246
-
247
- if (debounceTimer) {
248
- clearTimeout(debounceTimer);
249
- }
250
-
251
- const timer = setTimeout(() => {
252
- if (!isStaticData) {
253
- setPagination(prev => ({ ...prev, current: 1 }));
254
- }
255
- }, filter?.debounce || 300);
256
-
257
- setDebounceTimer(timer);
258
- }, [debounceTimer, filter?.debounce, isStaticData]);
259
-
260
- // 清除防抖定时器
261
- useEffect(() => {
262
- return () => {
263
- if (debounceTimer) {
264
- clearTimeout(debounceTimer);
265
- }
266
- };
267
- }, [debounceTimer]);
268
-
269
- // 初始化数据
270
- useEffect(() => {
271
- if (immediate && !isStaticData) {
272
- fetchData();
273
- } else if (isStaticData) {
274
- setData(staticData);
275
- setTotal(staticData.length);
276
- }
277
- }, [fetchData, immediate, isStaticData, staticData]);
278
-
279
- // 刷新数据
280
- const refresh = useCallback(() => {
281
- if (isStaticData) {
282
- setData(staticData);
283
- setTotal(staticData.length);
284
- } else {
285
- fetchData();
286
- }
287
- }, [fetchData, isStaticData, staticData]);
288
-
289
- // 搜索
290
- const search = useCallback((params: Record<string, any>) => {
291
- setSearchParams(prev => ({ ...prev, ...params }));
292
- if (!isStaticData) {
293
- setPagination(prev => ({ ...prev, current: 1 }));
294
- }
295
- }, [isStaticData]);
296
-
297
- // 重置
298
- const reset = useCallback(() => {
299
- setSearchParams(initialParams);
300
- setFilterValue('');
301
- if (!isStaticData) {
302
- setPagination({ current: 1, pageSize: 10 });
303
- }
304
- }, [initialParams, isStaticData]);
305
-
306
- // 分页变化处理
307
- const handlePaginationChange = useCallback((current: number, pageSize?: number) => {
308
- setPagination(prev => ({
309
- current,
310
- pageSize: pageSize || prev.pageSize,
311
- }));
312
- }, []);
313
-
314
- // 计算最终显示的数据
315
- const displayData = useMemo(() => {
316
- return filter ? filteredData : data;
317
- }, [filter, filteredData, data]);
318
-
319
- // 计算分页后的数据
320
- const paginatedData = useMemo(() => {
321
- if (paginationConfig === false || isStaticData) {
322
- return displayData;
323
- }
324
-
325
- const startIndex = (pagination.current - 1) * pagination.pageSize;
326
- const endIndex = startIndex + pagination.pageSize;
327
- return displayData.slice(startIndex, endIndex);
328
- }, [displayData, pagination.current, pagination.pageSize, paginationConfig, isStaticData]);
329
-
330
- // 计算显示的总数
331
- const displayTotal = useMemo(() => {
332
- if (isStaticData) {
333
- return filter ? filteredData.length : data.length;
334
- }
335
- return filter ? filteredData.length : total;
336
- }, [isStaticData, filter, filteredData.length, data.length, total]);
337
-
338
- // 表格配置
339
- const tableProps: TableProps<T> = useMemo(() => ({
340
- columns,
341
- dataSource: paginatedData,
342
- loading,
343
- rowKey,
344
- pagination: false,
345
- scroll: { x: 800 },
346
- }), [columns, paginatedData, loading, rowKey]);
347
-
348
- // 分页配置
349
- const paginationProps: PaginationProps = useMemo(() => {
350
- if (paginationConfig === false) {
351
- return {} as PaginationProps;
352
- }
353
-
354
- const baseProps: PaginationProps = {
355
- current: pagination.current,
356
- pageSize: pagination.pageSize,
357
- total: displayTotal,
358
- showSizeChanger: true,
359
- showQuickJumper: true,
360
- showTotal: (total, range) =>
361
- `第 ${range[0]}-${range[1]} 条,共 ${total} 条`,
362
- onChange: handlePaginationChange,
363
- onShowSizeChange: handlePaginationChange,
364
- };
365
-
366
- // 合并自定义分页配置
367
- return typeof paginationConfig === 'object'
368
- ? { ...baseProps, ...paginationConfig }
369
- : baseProps;
370
- }, [pagination.current, pagination.pageSize, displayTotal, handlePaginationChange, paginationConfig]);
371
-
372
- // 筛选输入框配置
373
- const filterProps: InputProps = useMemo(() => ({
374
- value: filterValue,
375
- onChange: (e) => handleFilterChange(e.target.value),
376
- placeholder: filter?.placeholder || `搜索${filter?.dataIndex}`,
377
- allowClear: true,
378
- style: { width: 250 },
379
- }), [filterValue, handleFilterChange, filter]);
380
-
381
- return {
382
- // 核心属性
383
- tableProps,
384
- data: paginatedData,
385
- loading,
386
- total: displayTotal,
387
-
388
- // 分页相关
389
- paginationProps,
390
- current: pagination.current,
391
- pageSize: pagination.pageSize,
392
-
393
- // 筛选相关
394
- filterProps,
395
- filterValue,
396
-
397
- // 操作方法
398
- refresh,
399
- search,
400
- reset,
401
- setData,
402
- setLoading,
403
- };
404
- };
405
-
406
- export default useDataTable;
package/tsconfig.json DELETED
@@ -1,17 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "es5",
4
- "module": "esnext",
5
- "lib": ["dom", "esnext"],
6
- "declaration": true,
7
- "outDir": "dist",
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "jsx": "react-jsx",
13
- "moduleResolution": "node"
14
- },
15
- "include": ["src"],
16
- "exclude": ["node_modules", "dist", "tests"]
17
- }
package/yarn-error.log DELETED
@@ -1,57 +0,0 @@
1
- Arguments:
2
- /Users/wangdong/.nvm/versions/node/v8.11.2/bin/node /Users/wangdong/.nvm/versions/node/v8.11.2/bin/yarn install
3
-
4
- PATH:
5
- /Users/wangdong/.nvm/versions/node/v8.11.2/bin:/Library/Frameworks/Python.framework/Versions/3.9/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Users/wangdong/.nvm/versions/node/v8.11.2/bin:/Users/wangdong/Library/pnpm:/Library/Frameworks/Python.framework/Versions/3.9/bin:/usr/local/mysql/bin:/usr/local/mysql/bin
6
-
7
- Yarn version:
8
- 1.22.10
9
-
10
- Node version:
11
- 8.11.2
12
-
13
- Platform:
14
- darwin x64
15
-
16
- Trace:
17
- Error: certificate has expired
18
- at TLSSocket.<anonymous> (_tls_wrap.js:1105:38)
19
- at emitNone (events.js:106:13)
20
- at TLSSocket.emit (events.js:208:7)
21
- at TLSSocket._finishInit (_tls_wrap.js:639:8)
22
- at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:469:38)
23
-
24
- npm manifest:
25
- {
26
- "name": "antd-hooks",
27
- "version": "1.0.0",
28
- "description": "A collection of enhanced hooks for Ant Design",
29
- "main": "index.js",
30
- "scripts": {
31
- "test": "echo \"Error: no test specified\" && exit 1"
32
- },
33
- "keywords": [
34
- "react",
35
- "hooks",
36
- "antd",
37
- "ant-design"
38
- ],
39
- "author": "wangdong <785414514@qq.com>",
40
- "license": "ISC",
41
- "peerDependencies": {
42
- "react": ">=16.8.0",
43
- "react-dom": ">=16.8.0",
44
- "antd": ">=4.0.0"
45
- },
46
- "devDependencies": {
47
- "@types/react": "^18.0.0",
48
- "rollup": "^3.0.0",
49
- "typescript": "^4.0.0"
50
- }
51
- }
52
-
53
- yarn manifest:
54
- No manifest
55
-
56
- Lockfile:
57
- No lockfile
File without changes