@sum-one/components 0.0.1

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,111 @@
1
+ import * as _$vue from "vue";
2
+ import { Component, MaybeRefOrGetter, Ref, VNodeChild } from "vue";
3
+ import * as _$element_plus0 from "element-plus";
4
+ import { PaginationProps, TableColumnInstance } from "element-plus";
5
+
6
+ //#region ../hooks/dist/index.d.mts
7
+ //#endregion
8
+ //#region src/use-table/types.d.ts
9
+ interface DataFields {
10
+ responseFields?: {
11
+ list?: string;
12
+ total?: string;
13
+ };
14
+ paginationFields?: {
15
+ page?: string;
16
+ pageSize?: string;
17
+ };
18
+ }
19
+ interface FetchParams extends Record<string, any> {
20
+ page?: number;
21
+ pageSize?: number;
22
+ }
23
+ interface DefaultPagination {
24
+ page?: number;
25
+ pageSize?: number;
26
+ }
27
+ interface PaginationState {
28
+ page: number;
29
+ pageSize: number;
30
+ total: number;
31
+ }
32
+ interface UseTableOptions<T = any> {
33
+ /** 数据获取函数 */
34
+ request: (params: FetchParams, signal?: AbortSignal) => Promise<Record<string, any>>;
35
+ /** 除分页之外的业务参数 */
36
+ queryParams?: MaybeRefOrGetter<Record<string, any>>;
37
+ /** 是否立即执行 */
38
+ immediate?: boolean;
39
+ /** 是否监听查询参数变化自动重新查询 */
40
+ watchQueryParams?: boolean;
41
+ /** 默认的分页配置 */
42
+ defaultPagination?: DefaultPagination;
43
+ /** 发送请求前对参数进行处理 */
44
+ paramsHandler?: (params: FetchParams) => FetchParams;
45
+ /** 数据转换函数 */
46
+ transform?: (data: T[]) => T[];
47
+ /** 请求成功的回调 */
48
+ onSuccess?: (data: T[], total: number) => void;
49
+ /** 请求失败的回调 */
50
+ onError?: (error: unknown) => void;
51
+ /**
52
+ * 请求和响应中的分页/列表字段映射
53
+ */
54
+ dataFields?: DataFields;
55
+ }
56
+ interface UseTableResult<T = any> {
57
+ data: Ref<T[]>;
58
+ loading: Ref<boolean>;
59
+ error: Ref<unknown>;
60
+ pagination: PaginationState;
61
+ refresh: () => Promise<T[] | undefined>;
62
+ search: () => void;
63
+ handlePageChange: (page: number) => void;
64
+ handleSizeChange: (pageSize: number) => void;
65
+ } //#endregion
66
+ //#region src/use-table/index.d.ts
67
+ declare function useTable<T = any>(options: UseTableOptions<T>): UseTableResult<T>; //#endregion
68
+ //#endregion
69
+ //#region src/table/types.d.ts
70
+ type TableColumnProp<T> = T extends Record<string, any> ? Extract<keyof T, string> : string;
71
+ interface TableRenderScope<T = any> {
72
+ row: T;
73
+ column: TableColumnInstance;
74
+ $index: number;
75
+ cellValue: any;
76
+ }
77
+ interface TableColumns<T = any> extends Omit<TableColumnInstance['$props'], 'label' | 'prop'> {
78
+ label?: string | Component;
79
+ prop?: TableColumnProp<T>;
80
+ render?: (scope: TableRenderScope<T>) => VNodeChild;
81
+ children?: TableColumns<T>[];
82
+ }
83
+ interface IProps {
84
+ columns: TableColumns[];
85
+ rowKey?: string;
86
+ align?: 'left' | 'center' | 'right';
87
+ selection?: boolean;
88
+ index?: boolean;
89
+ showPagination?: boolean;
90
+ pagination?: Partial<PaginationProps>;
91
+ request: UseTableOptions['request'];
92
+ requestAuto?: UseTableOptions['immediate'];
93
+ paramsHandler?: UseTableOptions['paramsHandler'];
94
+ transform?: UseTableOptions['transform'];
95
+ onSuccess?: UseTableOptions['onSuccess'];
96
+ onError?: UseTableOptions['onError'];
97
+ dataFields?: UseTableOptions['dataFields'];
98
+ }
99
+ //#endregion
100
+ //#region src/table/table.vue.d.ts
101
+ declare const __VLS_export: _$vue.DefineComponent<IProps, {}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<IProps> & Readonly<{}>, {
102
+ align: "left" | "center" | "right";
103
+ index: boolean;
104
+ showPagination: boolean;
105
+ pagination: Partial<_$element_plus0.PaginationProps>;
106
+ requestAuto: useTable["immediate"];
107
+ }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
108
+ declare const _default: typeof __VLS_export;
109
+ //#endregion
110
+ export { IProps, _default as SumTable, TableColumns, TableRenderScope };
111
+ //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs ADDED
@@ -0,0 +1,459 @@
1
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createSlots, createVNode, defineComponent, mergeProps, normalizeStyle, openBlock, reactive, renderList, resolveComponent, resolveDirective, resolveDynamicComponent, toValue, unref, useAttrs, watch, withCtx, withDirectives } from "vue";
2
+ import "element-plus";
3
+ import { useAsyncState } from "@vueuse/core";
4
+ //#region ../hooks/dist/index.mjs
5
+ function getValueByPath(source, path) {
6
+ return path.split(".").reduce((value, key) => value?.[key], source);
7
+ }
8
+ function useTable(options) {
9
+ const { request, queryParams, immediate = true, watchQueryParams, defaultPagination = {}, paramsHandler, transform, onError, onSuccess, dataFields } = options;
10
+ const listField = dataFields?.responseFields?.list ?? "list";
11
+ const totalField = dataFields?.responseFields?.total ?? "total";
12
+ const pageField = dataFields?.paginationFields?.page ?? "page";
13
+ const pageSizeField = dataFields?.paginationFields?.pageSize ?? "pageSize";
14
+ const { page: defaultCurrentPage = 1, pageSize: defaultPageSize = 10 } = defaultPagination;
15
+ const pagination = reactive({
16
+ page: defaultCurrentPage,
17
+ pageSize: defaultPageSize,
18
+ total: 0
19
+ });
20
+ const getQueryParams = () => toValue(queryParams);
21
+ let abortController;
22
+ let latestData = [];
23
+ const buildRequestParams = () => {
24
+ const totalParams = {
25
+ ...getQueryParams(),
26
+ [pageField]: pagination.page,
27
+ [pageSizeField]: pagination.pageSize
28
+ };
29
+ return paramsHandler ? paramsHandler(totalParams) : totalParams;
30
+ };
31
+ const fetchData = async () => {
32
+ abortController?.abort();
33
+ const controller = new AbortController();
34
+ abortController = controller;
35
+ try {
36
+ const response = await request(buildRequestParams(), controller.signal);
37
+ if (controller.signal.aborted) return latestData;
38
+ const list = getValueByPath(response, listField);
39
+ const total = getValueByPath(response, totalField);
40
+ if (!Array.isArray(list)) throw new TypeError(`Expected response.${listField} to be an array`);
41
+ if (typeof total !== "number") throw new TypeError(`Expected response.${totalField} to be a number`);
42
+ pagination.total = total;
43
+ onSuccess?.(list, total);
44
+ const finalData = transform ? transform(list) : list;
45
+ latestData = finalData;
46
+ return finalData;
47
+ } catch (err) {
48
+ if (controller.signal.aborted) return latestData;
49
+ onError?.(err);
50
+ throw err;
51
+ } finally {
52
+ if (abortController === controller) abortController = void 0;
53
+ }
54
+ };
55
+ const { state: data, isLoading: loading, error, execute } = useAsyncState(fetchData, [], {
56
+ immediate,
57
+ resetOnExecute: false
58
+ });
59
+ const refresh = () => execute();
60
+ const search = () => {
61
+ pagination.page = 1;
62
+ execute();
63
+ };
64
+ const handlePageChange = (page) => {
65
+ pagination.page = page;
66
+ execute();
67
+ };
68
+ const handleSizeChange = (pageSize) => {
69
+ pagination.pageSize = pageSize;
70
+ pagination.page = 1;
71
+ execute();
72
+ };
73
+ if (queryParams && watchQueryParams) watch(() => toValue(queryParams), () => {
74
+ search();
75
+ }, { deep: true });
76
+ return {
77
+ /** 表格数据 */
78
+ data,
79
+ /** 加载状态 */
80
+ loading,
81
+ /** 错误信息 */
82
+ error,
83
+ /** 分页信息 */
84
+ pagination,
85
+ /** 刷新数据(保持当前分页) */
86
+ refresh,
87
+ /** 重新查询(重置到第一页) */
88
+ search,
89
+ /** 分页变化处理 */
90
+ handlePageChange,
91
+ /** 每页数量变化处理 */
92
+ handleSizeChange
93
+ };
94
+ }
95
+ //#endregion
96
+ //#region src/table/pagination/index.vue
97
+ var pagination_default = /* @__PURE__ */ defineComponent({
98
+ __name: "index",
99
+ props: {
100
+ align: {
101
+ type: String,
102
+ required: false,
103
+ default: "right"
104
+ },
105
+ pageSize: {
106
+ type: Number,
107
+ required: false,
108
+ default: 10
109
+ },
110
+ defaultPageSize: {
111
+ type: Number,
112
+ required: false
113
+ },
114
+ total: {
115
+ type: Number,
116
+ required: false,
117
+ default: 0
118
+ },
119
+ pageCount: {
120
+ type: Number,
121
+ required: false
122
+ },
123
+ pagerCount: {
124
+ type: Number,
125
+ required: false
126
+ },
127
+ currentPage: {
128
+ type: Number,
129
+ required: false,
130
+ default: 1
131
+ },
132
+ defaultCurrentPage: {
133
+ type: Number,
134
+ required: false
135
+ },
136
+ layout: {
137
+ type: String,
138
+ required: false,
139
+ default: "total, sizes, prev, pager, next, jumper"
140
+ },
141
+ pageSizes: {
142
+ type: null,
143
+ required: false,
144
+ default: () => [
145
+ 10,
146
+ 20,
147
+ 30,
148
+ 50,
149
+ 100
150
+ ]
151
+ },
152
+ popperClass: {
153
+ type: String,
154
+ required: false
155
+ },
156
+ popperStyle: {
157
+ type: null,
158
+ required: false
159
+ },
160
+ prevText: {
161
+ type: String,
162
+ required: false
163
+ },
164
+ prevIcon: {
165
+ type: null,
166
+ required: false
167
+ },
168
+ nextText: {
169
+ type: String,
170
+ required: false
171
+ },
172
+ nextIcon: {
173
+ type: null,
174
+ required: false
175
+ },
176
+ teleported: {
177
+ type: Boolean,
178
+ required: false
179
+ },
180
+ small: {
181
+ type: Boolean,
182
+ required: false
183
+ },
184
+ size: {
185
+ type: String,
186
+ required: false
187
+ },
188
+ background: {
189
+ type: Boolean,
190
+ required: false
191
+ },
192
+ disabled: {
193
+ type: Boolean,
194
+ required: false
195
+ },
196
+ hideOnSinglePage: {
197
+ type: Boolean,
198
+ required: false
199
+ },
200
+ appendSizeTo: {
201
+ type: String,
202
+ required: false
203
+ }
204
+ },
205
+ emits: [
206
+ "update:currentPage",
207
+ "update:pageSize",
208
+ "currentChange",
209
+ "sizeChange"
210
+ ],
211
+ setup(__props, { emit: __emit }) {
212
+ const props = __props;
213
+ const emit = __emit;
214
+ const justifyContent = computed(() => {
215
+ return {
216
+ left: "flex-start",
217
+ center: "center",
218
+ right: "flex-end"
219
+ }[props.align];
220
+ });
221
+ function handleCurrentChange(page) {
222
+ emit("update:currentPage", page);
223
+ emit("currentChange", page);
224
+ }
225
+ function handleSizeChange(pageSize) {
226
+ emit("update:pageSize", pageSize);
227
+ emit("sizeChange", pageSize);
228
+ }
229
+ return (_ctx, _cache) => {
230
+ const _component_el_pagination = resolveComponent("el-pagination");
231
+ return props.total > 0 ? (openBlock(), createElementBlock("div", {
232
+ key: 0,
233
+ style: normalizeStyle({
234
+ display: "flex",
235
+ justifyContent: justifyContent.value,
236
+ marginTop: "16px"
237
+ })
238
+ }, [createVNode(_component_el_pagination, mergeProps(props, {
239
+ onCurrentChange: handleCurrentChange,
240
+ onSizeChange: handleSizeChange
241
+ }), null, 16)], 4)) : createCommentVNode("v-if", true);
242
+ };
243
+ }
244
+ });
245
+ Array.isArray;
246
+ function omit(obj, keys) {
247
+ if (obj == null) return {};
248
+ if (!keys || keys.length === 0) return { ...obj };
249
+ const keysSet = new Set(keys);
250
+ const result = {};
251
+ for (const [key, value] of Object.entries(obj)) if (!keysSet.has(key)) result[key] = value;
252
+ return result;
253
+ }
254
+ //#endregion
255
+ //#region src/table/table-data.vue
256
+ var table_data_default = /* @__PURE__ */ defineComponent({
257
+ __name: "table-data",
258
+ props: {
259
+ column: {
260
+ type: Object,
261
+ required: true
262
+ },
263
+ align: {
264
+ type: String,
265
+ required: true
266
+ }
267
+ },
268
+ setup(__props) {
269
+ const props = __props;
270
+ const RenderCell = defineComponent({
271
+ props: {
272
+ column: {
273
+ type: Object,
274
+ required: true
275
+ },
276
+ scope: {
277
+ type: Object,
278
+ required: true
279
+ }
280
+ },
281
+ setup(props) {
282
+ return () => {
283
+ const column = props.column;
284
+ const scope = props.scope;
285
+ return column.render?.({
286
+ ...scope,
287
+ cellValue: column.prop ? scope.row?.[column.prop] : void 0
288
+ });
289
+ };
290
+ }
291
+ });
292
+ return (_ctx, _cache) => {
293
+ const _component_table_data = resolveComponent("table-data", true);
294
+ const _component_el_table_column = resolveComponent("el-table-column");
295
+ return openBlock(), createBlock(_component_el_table_column, mergeProps(unref(omit)(__props.column, [
296
+ "label",
297
+ "align",
298
+ "render",
299
+ "children"
300
+ ]), {
301
+ label: typeof props.column.label === "string" ? props.column.label : void 0,
302
+ prop: props.column.prop,
303
+ align: props.column.align || props.align
304
+ }), createSlots({ _: 2 }, [props.column.children?.length ? {
305
+ name: "default",
306
+ fn: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(props.column.children, (item, index) => {
307
+ return openBlock(), createBlock(_component_table_data, {
308
+ key: item.prop || index,
309
+ align: props.column.align || props.align,
310
+ column: item
311
+ }, null, 8, ["align", "column"]);
312
+ }), 128))]),
313
+ key: "0"
314
+ } : props.column.render ? {
315
+ name: "default",
316
+ fn: withCtx((scope) => [createVNode(unref(RenderCell), {
317
+ column: props.column,
318
+ scope
319
+ }, null, 8, ["column", "scope"])]),
320
+ key: "1"
321
+ } : void 0, props.column.label && typeof props.column.label !== "string" ? {
322
+ name: "header",
323
+ fn: withCtx(() => [(openBlock(), createBlock(resolveDynamicComponent(props.column.label)))]),
324
+ key: "2"
325
+ } : void 0]), 1040, [
326
+ "label",
327
+ "prop",
328
+ "align"
329
+ ]);
330
+ };
331
+ }
332
+ });
333
+ //#endregion
334
+ //#region src/table/table.vue
335
+ var table_default = /* @__PURE__ */ defineComponent({
336
+ __name: "table",
337
+ props: {
338
+ columns: {
339
+ type: Array,
340
+ required: true
341
+ },
342
+ rowKey: {
343
+ type: String,
344
+ required: false
345
+ },
346
+ align: {
347
+ type: String,
348
+ required: false,
349
+ default: "center"
350
+ },
351
+ selection: {
352
+ type: Boolean,
353
+ required: false
354
+ },
355
+ index: {
356
+ type: Boolean,
357
+ required: false,
358
+ default: false
359
+ },
360
+ showPagination: {
361
+ type: Boolean,
362
+ required: false,
363
+ default: true
364
+ },
365
+ pagination: {
366
+ type: Object,
367
+ required: false,
368
+ default: () => ({})
369
+ },
370
+ request: {
371
+ type: Function,
372
+ required: true
373
+ },
374
+ requestAuto: {
375
+ type: Boolean,
376
+ required: false,
377
+ default: true
378
+ },
379
+ paramsHandler: {
380
+ type: Function,
381
+ required: false
382
+ },
383
+ transform: {
384
+ type: Function,
385
+ required: false
386
+ },
387
+ onSuccess: {
388
+ type: Function,
389
+ required: false
390
+ },
391
+ onError: {
392
+ type: Function,
393
+ required: false
394
+ },
395
+ dataFields: {
396
+ type: Object,
397
+ required: false
398
+ }
399
+ },
400
+ setup(__props) {
401
+ const props = __props;
402
+ const attrs = useAttrs();
403
+ const { data, loading, pagination, handlePageChange, handleSizeChange } = useTable({
404
+ ...props,
405
+ defaultPagination: {
406
+ page: props.pagination.currentPage ?? props.pagination.defaultCurrentPage,
407
+ pageSize: props.pagination.pageSize ?? props.pagination.defaultPageSize
408
+ }
409
+ });
410
+ return (_ctx, _cache) => {
411
+ const _component_el_table_column = resolveComponent("el-table-column");
412
+ const _component_el_table = resolveComponent("el-table");
413
+ const _directive_loading = resolveDirective("loading");
414
+ return openBlock(), createElementBlock("div", null, [
415
+ createCommentVNode(" <span v-if=\"props.title\">{{ props.title }}</span> "),
416
+ withDirectives((openBlock(), createBlock(_component_el_table, mergeProps({
417
+ ...unref(attrs),
418
+ ...props
419
+ }, { data: unref(data) }), {
420
+ default: withCtx(() => [
421
+ props.selection ? (openBlock(), createBlock(_component_el_table_column, {
422
+ key: 0,
423
+ type: "selection"
424
+ })) : createCommentVNode("v-if", true),
425
+ props.index ? (openBlock(), createBlock(_component_el_table_column, {
426
+ key: 1,
427
+ type: "index"
428
+ })) : createCommentVNode("v-if", true),
429
+ (openBlock(true), createElementBlock(Fragment, null, renderList(props.columns, (item, index) => {
430
+ return openBlock(), createBlock(table_data_default, {
431
+ key: item.prop || index,
432
+ align: props.align,
433
+ column: item
434
+ }, null, 8, ["align", "column"]);
435
+ }), 128))
436
+ ]),
437
+ _: 1
438
+ }, 16, ["data"])), [[_directive_loading, unref(loading)]]),
439
+ props.showPagination ? (openBlock(), createBlock(pagination_default, mergeProps({ key: 0 }, props.pagination, {
440
+ "current-page": unref(pagination).page,
441
+ "page-size": unref(pagination).pageSize,
442
+ total: unref(pagination).total,
443
+ onCurrentChange: unref(handlePageChange),
444
+ onSizeChange: unref(handleSizeChange)
445
+ }), null, 16, [
446
+ "current-page",
447
+ "page-size",
448
+ "total",
449
+ "onCurrentChange",
450
+ "onSizeChange"
451
+ ])) : createCommentVNode("v-if", true)
452
+ ]);
453
+ };
454
+ }
455
+ });
456
+ //#endregion
457
+ export { table_default as SumTable };
458
+
459
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../hooks/dist/index.mjs","../src/table/pagination/index.vue","../src/table/pagination/index.vue","../../utils/dist/index.mjs","../src/table/table-data.vue","../src/table/table-data.vue","../src/table/table.vue","../src/table/table.vue"],"sourcesContent":["import { ElDialog } from \"element-plus\";\nimport { createApp, h, reactive, ref, toValue, watch } from \"vue\";\nimport { useAsyncState } from \"@vueuse/core\";\n//#region src/use-modal/index.ts\n/** 动画持续时间(毫秒) */\nconst ANIMATION_DURATION = 1e3;\nconst DEFAULT_MODAL_PROPS = {\n\twidth: \"50%\",\n\ttop: \"15vh\",\n\tcloseOnClickModal: false,\n\tcloseOnPressEscape: true,\n\tdestroyOnClose: true,\n\tdraggable: true,\n\tlockScroll: true\n};\nfunction useModal(component, { props, modalProps }) {\n\tconst open = ref(true);\n\tconst componentInstance = ref(null);\n\tlet unmountTimer = null;\n\tconst dialogComponent = () => {\n\t\tconst { slots: modalSlots, ...restModalProps } = modalProps ?? {};\n\t\treturn h(ElDialog, {\n\t\t\t...DEFAULT_MODAL_PROPS,\n\t\t\t...restModalProps,\n\t\t\tmodelValue: open.value,\n\t\t\tbeforeClose(done) {\n\t\t\t\tdone();\n\t\t\t\tunmount();\n\t\t\t}\n\t\t}, {\n\t\t\tdefault: () => h(component, {\n\t\t\t\t...props,\n\t\t\t\tref: componentInstance\n\t\t\t}),\n\t\t\t...modalSlots\n\t\t});\n\t};\n\tlet app = null;\n\tlet container = null;\n\ttry {\n\t\tapp = createApp(dialogComponent);\n\t\tcontainer = document.createElement(\"div\");\n\t\tdocument.body.appendChild(container);\n\t\tapp.mount(container);\n\t} catch (error) {\n\t\tconsole.error(\"Failed to create modal:\", error);\n\t\tthrow error;\n\t}\n\tfunction unmount() {\n\t\tif (!open.value) return;\n\t\topen.value = false;\n\t\tif (unmountTimer) clearTimeout(unmountTimer);\n\t\tunmountTimer = setTimeout(() => {\n\t\t\ttry {\n\t\t\t\tif (app) {\n\t\t\t\t\tapp.unmount();\n\t\t\t\t\tapp = null;\n\t\t\t\t}\n\t\t\t\tif (container?.parentNode) {\n\t\t\t\t\tcontainer.parentNode.removeChild(container);\n\t\t\t\t\tcontainer = null;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(error);\n\t\t\t} finally {\n\t\t\t\tunmountTimer = null;\n\t\t\t}\n\t\t}, ANIMATION_DURATION);\n\t}\n\treturn {\n\t\tclose: unmount,\n\t\tcomponentInstance,\n\t\tisOpen: open\n\t};\n}\n//#endregion\n//#region src/use-table/index.ts\nfunction getValueByPath(source, path) {\n\treturn path.split(\".\").reduce((value, key) => value?.[key], source);\n}\nfunction useTable(options) {\n\tconst { request, queryParams, immediate = true, watchQueryParams, defaultPagination = {}, paramsHandler, transform, onError, onSuccess, dataFields } = options;\n\tconst listField = dataFields?.responseFields?.list ?? \"list\";\n\tconst totalField = dataFields?.responseFields?.total ?? \"total\";\n\tconst pageField = dataFields?.paginationFields?.page ?? \"page\";\n\tconst pageSizeField = dataFields?.paginationFields?.pageSize ?? \"pageSize\";\n\tconst { page: defaultCurrentPage = 1, pageSize: defaultPageSize = 10 } = defaultPagination;\n\tconst pagination = reactive({\n\t\tpage: defaultCurrentPage,\n\t\tpageSize: defaultPageSize,\n\t\ttotal: 0\n\t});\n\tconst getQueryParams = () => toValue(queryParams);\n\tlet abortController;\n\tlet latestData = [];\n\tconst buildRequestParams = () => {\n\t\tconst totalParams = {\n\t\t\t...getQueryParams(),\n\t\t\t[pageField]: pagination.page,\n\t\t\t[pageSizeField]: pagination.pageSize\n\t\t};\n\t\treturn paramsHandler ? paramsHandler(totalParams) : totalParams;\n\t};\n\tconst fetchData = async () => {\n\t\tabortController?.abort();\n\t\tconst controller = new AbortController();\n\t\tabortController = controller;\n\t\ttry {\n\t\t\tconst response = await request(buildRequestParams(), controller.signal);\n\t\t\tif (controller.signal.aborted) return latestData;\n\t\t\tconst list = getValueByPath(response, listField);\n\t\t\tconst total = getValueByPath(response, totalField);\n\t\t\tif (!Array.isArray(list)) throw new TypeError(`Expected response.${listField} to be an array`);\n\t\t\tif (typeof total !== \"number\") throw new TypeError(`Expected response.${totalField} to be a number`);\n\t\t\tpagination.total = total;\n\t\t\tonSuccess?.(list, total);\n\t\t\tconst finalData = transform ? transform(list) : list;\n\t\t\tlatestData = finalData;\n\t\t\treturn finalData;\n\t\t} catch (err) {\n\t\t\tif (controller.signal.aborted) return latestData;\n\t\t\tonError?.(err);\n\t\t\tthrow err;\n\t\t} finally {\n\t\t\tif (abortController === controller) abortController = void 0;\n\t\t}\n\t};\n\tconst { state: data, isLoading: loading, error, execute } = useAsyncState(fetchData, [], {\n\t\timmediate,\n\t\tresetOnExecute: false\n\t});\n\tconst refresh = () => execute();\n\tconst search = () => {\n\t\tpagination.page = 1;\n\t\texecute();\n\t};\n\tconst handlePageChange = (page) => {\n\t\tpagination.page = page;\n\t\texecute();\n\t};\n\tconst handleSizeChange = (pageSize) => {\n\t\tpagination.pageSize = pageSize;\n\t\tpagination.page = 1;\n\t\texecute();\n\t};\n\tif (queryParams && watchQueryParams) watch(() => toValue(queryParams), () => {\n\t\tsearch();\n\t}, { deep: true });\n\treturn {\n\t\t/** 表格数据 */\n\t\tdata,\n\t\t/** 加载状态 */\n\t\tloading,\n\t\t/** 错误信息 */\n\t\terror,\n\t\t/** 分页信息 */\n\t\tpagination,\n\t\t/** 刷新数据(保持当前分页) */\n\t\trefresh,\n\t\t/** 重新查询(重置到第一页) */\n\t\tsearch,\n\t\t/** 分页变化处理 */\n\t\thandlePageChange,\n\t\t/** 每页数量变化处理 */\n\t\thandleSizeChange\n\t};\n}\n//#endregion\nexport { useModal, useTable };\n\n//# sourceMappingURL=index.mjs.map","<script setup lang=\"ts\">\nimport type { PaginationProps } from 'element-plus'\nimport { computed } from 'vue'\n\ninterface IProps extends Partial<PaginationProps> {\n align?: 'left' | 'center' | 'right'\n}\n\nconst props = withDefaults(defineProps<IProps>(), {\n currentPage: 1,\n pageSize: 10,\n total: 0,\n pageSizes: () => [10, 20, 30, 50, 100],\n layout: 'total, sizes, prev, pager, next, jumper',\n align: 'right'\n})\n\nconst emit = defineEmits<{\n 'update:currentPage': [page: number]\n 'update:pageSize': [pageSize: number]\n 'currentChange': [page: number]\n 'sizeChange': [pageSize: number]\n}>()\n\nconst justifyContent = computed(() => {\n const alignMap = {\n left: 'flex-start',\n center: 'center',\n right: 'flex-end'\n }\n\n return alignMap[props.align]\n})\n\nfunction handleCurrentChange(page: number): void {\n emit('update:currentPage', page)\n emit('currentChange', page)\n}\n\nfunction handleSizeChange(pageSize: number): void {\n emit('update:pageSize', pageSize)\n emit('sizeChange', pageSize)\n}\n</script>\n\n<template>\n <div\n v-if=\"props.total > 0\"\n :style=\"{\n display: 'flex',\n justifyContent,\n marginTop: '16px',\n }\"\n >\n <el-pagination\n v-bind=\"props\"\n @current-change=\"handleCurrentChange\"\n @size-change=\"handleSizeChange\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { PaginationProps } from 'element-plus'\nimport { computed } from 'vue'\n\ninterface IProps extends Partial<PaginationProps> {\n align?: 'left' | 'center' | 'right'\n}\n\nconst props = withDefaults(defineProps<IProps>(), {\n currentPage: 1,\n pageSize: 10,\n total: 0,\n pageSizes: () => [10, 20, 30, 50, 100],\n layout: 'total, sizes, prev, pager, next, jumper',\n align: 'right'\n})\n\nconst emit = defineEmits<{\n 'update:currentPage': [page: number]\n 'update:pageSize': [pageSize: number]\n 'currentChange': [page: number]\n 'sizeChange': [pageSize: number]\n}>()\n\nconst justifyContent = computed(() => {\n const alignMap = {\n left: 'flex-start',\n center: 'center',\n right: 'flex-end'\n }\n\n return alignMap[props.align]\n})\n\nfunction handleCurrentChange(page: number): void {\n emit('update:currentPage', page)\n emit('currentChange', page)\n}\n\nfunction handleSizeChange(pageSize: number): void {\n emit('update:pageSize', pageSize)\n emit('sizeChange', pageSize)\n}\n</script>\n\n<template>\n <div\n v-if=\"props.total > 0\"\n :style=\"{\n display: 'flex',\n justifyContent,\n marginTop: '16px',\n }\"\n >\n <el-pagination\n v-bind=\"props\"\n @current-change=\"handleCurrentChange\"\n @size-change=\"handleSizeChange\"\n />\n </div>\n</template>\n","//#region src/array.ts\nconst isArray = Array.isArray;\n//#endregion\n//#region src/omit.ts\nfunction omit(obj, keys) {\n\tif (obj == null) return {};\n\tif (!keys || keys.length === 0) return { ...obj };\n\tconst keysSet = new Set(keys);\n\tconst result = {};\n\tfor (const [key, value] of Object.entries(obj)) if (!keysSet.has(key)) result[key] = value;\n\treturn result;\n}\n//#endregion\nexport { isArray, omit };\n\n//# sourceMappingURL=index.mjs.map","<script setup lang=\"ts\">\nimport type { TableColumns } from './types'\nimport { omit } from '@sum-one/utils'\nimport { defineComponent } from 'vue'\n\ninterface TableDataProps {\n column: TableColumns\n align: string\n}\nconst props = defineProps<TableDataProps>()\n\nconst RenderCell = defineComponent({\n props: {\n column: {\n type: Object,\n required: true\n },\n scope: {\n type: Object,\n required: true\n }\n },\n setup(props) {\n return () => {\n const column = props.column as TableColumns\n const scope = props.scope as any\n\n return column.render?.({\n ...scope,\n cellValue: column.prop ? scope.row?.[column.prop] : undefined\n })\n }\n }\n})\n</script>\n\n<template>\n <el-table-column\n v-bind=\" omit(column, ['label', 'align', 'render', 'children'])\"\n :label=\"typeof props.column.label === 'string' ? props.column.label : undefined\"\n :prop=\"props.column.prop\"\n :align=\"props.column.align || props.align\"\n >\n <template v-if=\"props.column.children?.length\" #default>\n <table-data\n v-for=\"(item, index) in props.column.children\"\n :key=\"item.prop || index\"\n :align=\"props.column.align || props.align\"\n :column=\"item\"\n />\n </template>\n\n <template v-else-if=\"props.column.render\" #default=\"scope\">\n <RenderCell :column=\"props.column\" :scope=\"scope\" />\n </template>\n\n <template v-if=\"props.column.label && typeof props.column.label !== 'string'\" #header>\n <component :is=\"props.column.label\" />\n </template>\n </el-table-column>\n</template>\n","<script setup lang=\"ts\">\nimport type { TableColumns } from './types'\nimport { omit } from '@sum-one/utils'\nimport { defineComponent } from 'vue'\n\ninterface TableDataProps {\n column: TableColumns\n align: string\n}\nconst props = defineProps<TableDataProps>()\n\nconst RenderCell = defineComponent({\n props: {\n column: {\n type: Object,\n required: true\n },\n scope: {\n type: Object,\n required: true\n }\n },\n setup(props) {\n return () => {\n const column = props.column as TableColumns\n const scope = props.scope as any\n\n return column.render?.({\n ...scope,\n cellValue: column.prop ? scope.row?.[column.prop] : undefined\n })\n }\n }\n})\n</script>\n\n<template>\n <el-table-column\n v-bind=\" omit(column, ['label', 'align', 'render', 'children'])\"\n :label=\"typeof props.column.label === 'string' ? props.column.label : undefined\"\n :prop=\"props.column.prop\"\n :align=\"props.column.align || props.align\"\n >\n <template v-if=\"props.column.children?.length\" #default>\n <table-data\n v-for=\"(item, index) in props.column.children\"\n :key=\"item.prop || index\"\n :align=\"props.column.align || props.align\"\n :column=\"item\"\n />\n </template>\n\n <template v-else-if=\"props.column.render\" #default=\"scope\">\n <RenderCell :column=\"props.column\" :scope=\"scope\" />\n </template>\n\n <template v-if=\"props.column.label && typeof props.column.label !== 'string'\" #header>\n <component :is=\"props.column.label\" />\n </template>\n </el-table-column>\n</template>\n","<script setup lang=\"ts\">\nimport type { IProps } from './types'\nimport { useTable } from '@sum-one/hooks'\nimport { useAttrs } from 'vue'\nimport SumPagination from './pagination/index.vue'\nimport TableData from './table-data.vue'\n\nconst props = withDefaults(defineProps<IProps>(), {\n requestAuto: true,\n index: false,\n align: 'center',\n showPagination: true,\n pagination: () => ({})\n})\nconst attrs = useAttrs()\n\nconst { data, loading, pagination, handlePageChange, handleSizeChange } = useTable({\n ...props,\n defaultPagination: {\n page: props.pagination.currentPage ?? props.pagination.defaultCurrentPage,\n pageSize: props.pagination.pageSize ?? props.pagination.defaultPageSize\n }\n})\n</script>\n\n<template>\n <div>\n <!-- <span v-if=\"props.title\">{{ props.title }}</span> -->\n <el-table v-loading=\"loading\" v-bind=\"{ ...attrs, ...props }\" :data=\"data\">\n <el-table-column v-if=\"props.selection\" type=\"selection\" />\n <el-table-column v-if=\"props.index\" type=\"index\" />\n <template\n v-for=\"(item, index) in props.columns\"\n :key=\"item.prop || index\"\n >\n <TableData :align=\"props.align\" :column=\"item\" />\n </template>\n </el-table>\n\n <SumPagination\n v-if=\"props.showPagination\"\n v-bind=\"props.pagination\"\n :current-page=\"pagination.page\"\n :page-size=\"pagination.pageSize\"\n :total=\"pagination.total\"\n @current-change=\"handlePageChange\"\n @size-change=\"handleSizeChange\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { IProps } from './types'\nimport { useTable } from '@sum-one/hooks'\nimport { useAttrs } from 'vue'\nimport SumPagination from './pagination/index.vue'\nimport TableData from './table-data.vue'\n\nconst props = withDefaults(defineProps<IProps>(), {\n requestAuto: true,\n index: false,\n align: 'center',\n showPagination: true,\n pagination: () => ({})\n})\nconst attrs = useAttrs()\n\nconst { data, loading, pagination, handlePageChange, handleSizeChange } = useTable({\n ...props,\n defaultPagination: {\n page: props.pagination.currentPage ?? props.pagination.defaultCurrentPage,\n pageSize: props.pagination.pageSize ?? props.pagination.defaultPageSize\n }\n})\n</script>\n\n<template>\n <div>\n <!-- <span v-if=\"props.title\">{{ props.title }}</span> -->\n <el-table v-loading=\"loading\" v-bind=\"{ ...attrs, ...props }\" :data=\"data\">\n <el-table-column v-if=\"props.selection\" type=\"selection\" />\n <el-table-column v-if=\"props.index\" type=\"index\" />\n <template\n v-for=\"(item, index) in props.columns\"\n :key=\"item.prop || index\"\n >\n <TableData :align=\"props.align\" :column=\"item\" />\n </template>\n </el-table>\n\n <SumPagination\n v-if=\"props.showPagination\"\n v-bind=\"props.pagination\"\n :current-page=\"pagination.page\"\n :page-size=\"pagination.pageSize\"\n :total=\"pagination.total\"\n @current-change=\"handlePageChange\"\n @size-change=\"handleSizeChange\"\n />\n </div>\n</template>\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@sum-one/components",
3
+ "type": "module",
4
+ "version": "0.0.1",
5
+ "packageManager": "pnpm@10.28.2",
6
+ "exports": {
7
+ "./package.json": "./package.json",
8
+ ".": {
9
+ "types": "./dist/index.d.mts",
10
+ "import": "./dist/index.mjs"
11
+ }
12
+ },
13
+ "main": "./dist/index.mjs",
14
+ "types": "./dist/index.d.mts",
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "dev": "tsdown --watch",
20
+ "build": "tsdown"
21
+ },
22
+ "publishConfig": {
23
+ "access": "public",
24
+ "registry": "https://registry.npmjs.org/"
25
+ },
26
+ "peerDependencies": {
27
+ "element-plus": ">=2.0.0 <3.0.0",
28
+ "vue": ">=3.2.0 <4.0.0"
29
+ },
30
+ "peerDependenciesMeta": {
31
+ "element-plus": {
32
+ "optional": true
33
+ }
34
+ },
35
+ "dependencies": {
36
+ "@vueuse/core": "^14.3.0"
37
+ },
38
+ "devDependencies": {
39
+ "@sum-one/config": "workspace:*",
40
+ "@sum-one/hooks": "workspace:*",
41
+ "@sum-one/utils": "workspace:*",
42
+ "@vitejs/plugin-vue": "^6.0.7",
43
+ "tsdown": "^0.22.0",
44
+ "vite": "^8.0.13",
45
+ "vue-tsc": "^3.3.1"
46
+ }
47
+ }