@vue-ui-kit/ant 2.4.3 → 2.4.4

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.
Files changed (36) hide show
  1. package/dist/cjs/index.js +3 -3
  2. package/dist/es/index.js +677 -582
  3. package/dist/index.d.ts +3080 -23
  4. package/package.json +1 -2
  5. package/src/declarations/antProxy.ts +12 -1
  6. package/src/index.ts +1 -0
  7. package/src/packages/components/PGrid.vue +68 -4
  8. package/src/packages/components/RenderAntCell.tsx +1 -1
  9. package/src/packages/components/RenderDefaultSlots.tsx +6 -2
  10. package/src/packages/store/renderStore.tsx +1 -1
  11. package/src/packages/utils/autoViewportBox.ts +156 -0
  12. package/src/packages/utils/config.ts +4 -0
  13. package/dist/declarations/antProxy.d.ts +0 -373
  14. package/dist/declarations/type.d.ts +0 -1
  15. package/dist/packages/components/CollapseCard.vue.d.ts +0 -29
  16. package/dist/packages/components/PCanvasTable.vue.d.ts +0 -177
  17. package/dist/packages/components/PForm.vue.d.ts +0 -22
  18. package/dist/packages/components/PFormCol.vue.d.ts +0 -23
  19. package/dist/packages/components/PFormGroup.vue.d.ts +0 -38
  20. package/dist/packages/components/PGroupBlock.vue.d.ts +0 -16
  21. package/dist/packages/components/PromisePicker.vue.d.ts +0 -25
  22. package/dist/packages/components/RenderAntCell.d.ts +0 -28
  23. package/dist/packages/components/RenderAntItem.d.ts +0 -18
  24. package/dist/packages/components/RenderDefaultSlots.d.ts +0 -34
  25. package/dist/packages/components/RenderEditCell.d.ts +0 -25
  26. package/dist/packages/components/RenderItemSlots.d.ts +0 -25
  27. package/dist/packages/components/RenderTitleSlots.d.ts +0 -16
  28. package/dist/packages/hooks/useMessage.d.ts +0 -8
  29. package/dist/packages/renders/Icon.d.ts +0 -4
  30. package/dist/packages/renders/TableInput.vue.d.ts +0 -25
  31. package/dist/packages/store/renderStore.d.ts +0 -16
  32. package/dist/packages/utils/AFormatters.d.ts +0 -9
  33. package/dist/packages/utils/config.d.ts +0 -30
  34. package/dist/packages/utils/core.d.ts +0 -10
  35. package/dist/packages/utils/is.d.ts +0 -4
  36. package/dist/packages/utils/treeHelper.d.ts +0 -19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue-ui-kit/ant",
3
- "version": "2.4.3",
3
+ "version": "2.4.4",
4
4
  "description": "Vue3 UI Kit based on Ant Design",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -77,7 +77,6 @@
77
77
  "typescript-transform-paths": "^3.5.0",
78
78
  "vite": "^8.0.8",
79
79
  "vite-plugin-dts": "^4.5.4",
80
- "vite-tsconfig-paths": "^5.1.4",
81
80
  "vue": "^3.4.38"
82
81
  }
83
82
  }
@@ -164,7 +164,8 @@ export interface ColumnProps<D extends Recordable = Recordable> extends Omit<
164
164
  export interface PButtonProps extends Omit<ButtonProps, 'type'> {
165
165
  content?: string | (() => any);
166
166
  icon?: string;
167
- type?: string;
167
+ /** 与 `a-button` 一致,便于模板类型检查 */
168
+ type?: ButtonProps['type'];
168
169
  }
169
170
 
170
171
  export interface ToolbarButtonProps extends PButtonProps {
@@ -231,6 +232,16 @@ export type PGridProps<D extends Recordable = Recordable, F extends Recordable =
231
232
  proxyConfig?: ProxyConfig<D, F>;
232
233
  tableConfig?: TableProps<D>;
233
234
  scrollMode?: 'outer' | 'inner';
235
+ /**
236
+ * 为 true 时根容器按视口从左上角铺满(与 v-rest 同源),用于外层未声明高度、靠内部撑开的布局。
237
+ * 偏移见 `autoBoxSizeOffset`。
238
+ */
239
+ autoBoxSize?: boolean;
240
+ /**
241
+ * `autoBoxSize` 时距视口右侧/底部的预留像素;数字或 `"12px"` 同时作用于两侧;对象可分别指定 `right` / `bottom`。
242
+ * 未传时使用 `setUIKitConfig({ grid: { autoBoxSizeOffset } })` 的全局值。
243
+ */
244
+ autoBoxSizeOffset?: number | string | { right?: number; bottom?: number };
234
245
  // 重置后不自动提交
235
246
  lazyReset?: boolean;
236
247
  /**
package/src/index.ts CHANGED
@@ -40,6 +40,7 @@ export default {
40
40
 
41
41
  // 导出所有类型
42
42
  export * from '#/antProxy';
43
+ export * from '@/utils/autoViewportBox';
43
44
  export * from '@/utils/core';
44
45
 
45
46
  // 导出配置方法
@@ -11,6 +11,12 @@
11
11
  import { $confirm } from '@/hooks/useMessage';
12
12
  import Icon from '@/renders/Icon';
13
13
  import { getGridDefaults } from '@/utils/config';
14
+ import {
15
+ createAutoViewportBoxController,
16
+ parseAutoViewportBoxOffset,
17
+ type AutoViewportBoxController,
18
+ type AutoViewportBoxOffsetInput,
19
+ } from '@/utils/autoViewportBox';
14
20
  import { cleanCol, defaultLabelCol } from '@/utils/core';
15
21
  import { isGoodValue } from '@/utils/is';
16
22
  import { eachTree } from '@/utils/treeHelper';
@@ -55,6 +61,7 @@
55
61
  lazyReset: () => getGridDefaults().lazyReset ?? false,
56
62
  fitHeight: () => getGridDefaults().fitHeight ?? 30,
57
63
  striped: () => getGridDefaults().striped ?? false,
64
+ autoBoxSize: false,
58
65
  });
59
66
 
60
67
  const {
@@ -67,6 +74,16 @@
67
74
  selectConfig,
68
75
  scrollMode,
69
76
  } = toRefs(props);
77
+
78
+ /** 局部 `autoBoxSizeOffset` 优先,否则用 `getGridDefaults().autoBoxSizeOffset`(`setUIKitConfig`) */
79
+ const resolvedAutoBoxSizeOffset = computed<AutoViewportBoxOffsetInput>(() => {
80
+ const local = props.autoBoxSizeOffset;
81
+ if (local !== undefined && local !== null) {
82
+ return local;
83
+ }
84
+ return getGridDefaults().autoBoxSizeOffset as AutoViewportBoxOffsetInput;
85
+ });
86
+
70
87
  const loading = reactive({
71
88
  table: false,
72
89
  toolbar: false,
@@ -360,9 +377,9 @@
360
377
  return lazy ? Promise.resolve() : debounceFetchData();
361
378
  };
362
379
  const defaultTableConfig = {
363
- size: 'small',
380
+ size: 'small' as const,
364
381
  sticky: true,
365
- transformCellText: ({ text }) => {
382
+ transformCellText: ({ text }: { text: any }) => {
366
383
  return isArray(text) && text.length === 0 ? '-' : text;
367
384
  },
368
385
  };
@@ -412,6 +429,42 @@
412
429
  () => nextTick(() => resizeTable()),
413
430
  { flush: 'post' },
414
431
  );
432
+
433
+ let autoViewportBoxCtrl: AutoViewportBoxController | null = null;
434
+ const clearAutoViewportBox = () => {
435
+ autoViewportBoxCtrl?.destroy();
436
+ autoViewportBoxCtrl = null;
437
+ };
438
+ const syncAutoViewportBox = () => {
439
+ clearAutoViewportBox();
440
+ if (!props.autoBoxSize || !boxEl.value) return;
441
+ autoViewportBoxCtrl = createAutoViewportBoxController(
442
+ () => boxEl.value ?? undefined,
443
+ () => parseAutoViewportBoxOffset(resolvedAutoBoxSizeOffset.value),
444
+ {
445
+ onLayout: () => {
446
+ nextTick(() => resizeTable());
447
+ },
448
+ },
449
+ );
450
+ autoViewportBoxCtrl.attach();
451
+ };
452
+
453
+ watch(
454
+ () => props.autoBoxSize,
455
+ (on) => {
456
+ if (!on) clearAutoViewportBox();
457
+ else nextTick(() => syncAutoViewportBox());
458
+ },
459
+ );
460
+ watch(
461
+ resolvedAutoBoxSizeOffset,
462
+ () => {
463
+ if (props.autoBoxSize) autoViewportBoxCtrl?.update();
464
+ },
465
+ { deep: true },
466
+ );
467
+
415
468
  let resizeRaf: number | null = null;
416
469
 
417
470
  const resolveTableHeaderEl = (wrapper: HTMLElement): HTMLElement | null => {
@@ -511,7 +564,10 @@
511
564
  tableFooterResizeObserver.observe(tableFooterEl.value);
512
565
  }
513
566
  resetQueryFormData(props.manualFetch);
514
- nextTick(() => resizeTable());
567
+ nextTick(() => {
568
+ if (props.autoBoxSize) syncAutoViewportBox();
569
+ resizeTable();
570
+ });
515
571
  });
516
572
  const renderContent = (content: string | (() => any)) => {
517
573
  if (isFunction(content)) {
@@ -535,6 +591,7 @@
535
591
  ...c,
536
592
  }));
537
593
  onBeforeUnmount(() => {
594
+ clearAutoViewportBox();
538
595
  if (resizeRaf) cancelAnimationFrame(resizeRaf);
539
596
  window.removeEventListener('resize', resizeTable);
540
597
  observer.disconnect();
@@ -545,7 +602,14 @@
545
602
  });
546
603
  </script>
547
604
  <template>
548
- <div ref="boxEl" class="h-full p-wrapper flex flex-col gap-8px overflow-y-auto" v-bind="attrs">
605
+ <div
606
+ ref="boxEl"
607
+ :class="[
608
+ 'p-wrapper flex flex-col gap-8px overflow-y-auto',
609
+ autoBoxSize ? 'min-h-0 min-w-0 flex-1 w-full' : 'h-full',
610
+ ]"
611
+ v-bind="attrs"
612
+ >
549
613
  <div v-if="mode === 'bad'">请检查配置</div>
550
614
  <template v-else>
551
615
  <div
@@ -17,7 +17,7 @@ export default defineComponent(
17
17
  renderStore.renders[cellRender!.name]?.renderDefault?.(
18
18
  cellRender!,
19
19
  { data, row, field, rowIndex },
20
- props.defaultHandler,
20
+ props.defaultHandler ?? {},
21
21
  ) ?? null
22
22
  );
23
23
  };
@@ -1,5 +1,5 @@
1
1
  import { defineComponent } from 'vue';
2
- import { ColumnProps } from '#/antProxy';
2
+ import type { ColumnProps } from '#/antProxy';
3
3
  import { renderAntFormat } from '@/utils/AFormatters';
4
4
  import RenderAntCell from '@/components/RenderAntCell';
5
5
 
@@ -7,7 +7,11 @@ export default defineComponent(
7
7
  <D extends Recordable = Recordable>(props: {
8
8
  tableData: D[];
9
9
  row: D;
10
- column: ColumnProps<D>;
10
+ /**
11
+ * `PGrid` / `columns` 仍为 `ColumnProps<D>[]`;此处不能写 `ColumnProps<D>`:
12
+ * 模板里 `a-table` 的 `record` 无泛型上下文,会被推断为 `Record<string, any>`,与 `formatter` 里 `row: D` 逆变冲突(TS2322)。
13
+ */
14
+ column: ColumnProps<any>;
11
15
  rowIndex: number;
12
16
  defaultHandler?: {
13
17
  [key: string]: (...args: any[]) => any;
@@ -30,7 +30,7 @@ import { computed, ref, Ref } from 'vue';
30
30
 
31
31
  interface BtnOptions extends Omit<ButtonProps, 'type'> {
32
32
  content?: string;
33
- type?: string;
33
+ type?: ButtonProps['type'];
34
34
  getContent?: (p: RenderTableParams) => string;
35
35
  dynamicClassName?: (p: RenderTableParams) => string;
36
36
  dropdowns?: BtnOptions[];
@@ -0,0 +1,156 @@
1
+ /**
2
+ * 按视口从元素左上角铺满宽高(与 storybook 中 v-rest / v-height / v-width 同源思路),
3
+ * 用于外层未声明高度、需由根节点自行占满可视区域的场景。
4
+ */
5
+
6
+ export type AutoViewportBoxOffsetInput =
7
+ | number
8
+ | string
9
+ | { right?: number; bottom?: number }
10
+ | undefined;
11
+
12
+ export interface AutoViewportBoxOffset {
13
+ right: number;
14
+ bottom: number;
15
+ }
16
+
17
+ function parseSingle(value: unknown): number {
18
+ if (typeof value === 'number' && !Number.isNaN(value)) {
19
+ return value;
20
+ }
21
+ if (typeof value === 'string') {
22
+ const match = value.match(/^(-?\d+(?:\.\d+)?)(px)?$/i);
23
+ if (match) {
24
+ return Number.parseFloat(match[1]);
25
+ }
26
+ }
27
+ return 0;
28
+ }
29
+
30
+ /** 解析与 v-rest 一致的偏移:数字/字符串同时作用于 right+bottom;对象可单独指定 */
31
+ export function parseAutoViewportBoxOffset(
32
+ value: AutoViewportBoxOffsetInput,
33
+ ): AutoViewportBoxOffset {
34
+ if (value === undefined || value === null || value === '') {
35
+ return { right: 0, bottom: 0 };
36
+ }
37
+ if (typeof value === 'object' && !Array.isArray(value)) {
38
+ const o = value as { right?: number; bottom?: number };
39
+ return {
40
+ right: typeof o.right === 'number' ? o.right : 0,
41
+ bottom: typeof o.bottom === 'number' ? o.bottom : 0,
42
+ };
43
+ }
44
+ const single = parseSingle(value);
45
+ return { right: single, bottom: single };
46
+ }
47
+
48
+ function findResizeAncestor(start: Element | null): Element {
49
+ let el: Element | null = start?.parentElement ?? null;
50
+ while (el && el !== document.body) {
51
+ const overflow = window.getComputedStyle(el).overflow;
52
+ if (overflow === 'auto' || overflow === 'scroll' || overflow === 'hidden') {
53
+ return el;
54
+ }
55
+ el = el.parentElement;
56
+ }
57
+ return document.body;
58
+ }
59
+
60
+ /**
61
+ * 宽/高先按「视口内从元素左上角到右/下边缘」计算,再与**直接父元素**布局框取较小值,
62
+ * 避免嵌套在侧栏 + flex 列等窄容器里仍按整屏宽度赋值,从而撑出页面级横向滚动条。
63
+ */
64
+ export function applyViewportRestSize(el: HTMLElement, offset: AutoViewportBoxOffset): void {
65
+ const rect = el.getBoundingClientRect();
66
+ const vw = window.innerWidth;
67
+ const vh = window.innerHeight;
68
+
69
+ let targetW = Math.max(0, vw - rect.left - offset.right);
70
+ let targetH = Math.max(0, vh - rect.top - offset.bottom);
71
+
72
+ const parent = el.parentElement;
73
+ if (parent) {
74
+ const pr = parent.getBoundingClientRect();
75
+ if (pr.width > 0) {
76
+ targetW = Math.min(targetW, pr.width);
77
+ }
78
+ if (pr.height > 0) {
79
+ targetH = Math.min(targetH, pr.height);
80
+ }
81
+ }
82
+
83
+ el.style.width = `${targetW}px`;
84
+ el.style.height = `${targetH}px`;
85
+ }
86
+
87
+ function clearViewportBoxSize(el: HTMLElement): void {
88
+ el.style.width = '';
89
+ el.style.height = '';
90
+ }
91
+
92
+ export interface AutoViewportBoxControllerOptions {
93
+ /** 每次尺寸写回后回调(例如触发内部表格 resize) */
94
+ onLayout?: () => void;
95
+ }
96
+
97
+ export interface AutoViewportBoxController {
98
+ attach: () => void;
99
+ update: () => void;
100
+ destroy: () => void;
101
+ }
102
+
103
+ export function createAutoViewportBoxController(
104
+ getEl: () => HTMLElement | null | undefined,
105
+ getOffset: () => AutoViewportBoxOffset,
106
+ options?: AutoViewportBoxControllerOptions,
107
+ ): AutoViewportBoxController {
108
+ let resizeObserver: ResizeObserver | null = null;
109
+ let onWinResize: (() => void) | null = null;
110
+
111
+ const disconnect = () => {
112
+ if (resizeObserver) {
113
+ resizeObserver.disconnect();
114
+ resizeObserver = null;
115
+ }
116
+ if (onWinResize) {
117
+ window.removeEventListener('resize', onWinResize);
118
+ onWinResize = null;
119
+ }
120
+ };
121
+
122
+ const update = () => {
123
+ const el = getEl();
124
+ if (!el) return;
125
+ applyViewportRestSize(el, getOffset());
126
+ options?.onLayout?.();
127
+ };
128
+
129
+ const attach = () => {
130
+ disconnect();
131
+ const el = getEl();
132
+ if (!el) return;
133
+
134
+ onWinResize = () => update();
135
+ window.addEventListener('resize', onWinResize);
136
+
137
+ const scrollAncestor = findResizeAncestor(el);
138
+ resizeObserver = new ResizeObserver(() => update());
139
+ resizeObserver.observe(scrollAncestor);
140
+ if (el.parentElement) {
141
+ resizeObserver.observe(el.parentElement);
142
+ }
143
+
144
+ update();
145
+ };
146
+
147
+ return {
148
+ attach,
149
+ update,
150
+ destroy: () => {
151
+ disconnect();
152
+ const el = getEl();
153
+ if (el) clearViewportBoxSize(el);
154
+ },
155
+ };
156
+ }
@@ -1,4 +1,5 @@
1
1
  import { PFormProps, PGridProps } from '#/antProxy';
2
+ import type { AutoViewportBoxOffsetInput } from '@/utils/autoViewportBox';
2
3
  import { ConfigType } from 'e-virt-table';
3
4
  import { clone } from 'xe-utils';
4
5
  import type { VNode } from 'vue';
@@ -15,6 +16,8 @@ export interface UIKitConfig {
15
16
  fitHeight?: number;
16
17
  fitCanvasHeight?: number;
17
18
  striped?: boolean;
19
+ /** `PGrid` 开启 `autoBoxSize` 且未传 `autoBoxSizeOffset` 时的视口边距,与 props 类型一致 */
20
+ autoBoxSizeOffset?: AutoViewportBoxOffsetInput;
18
21
  };
19
22
  canvasTable?: ConfigType;
20
23
  /**
@@ -91,6 +94,7 @@ export function getGridDefaults(): Partial<PGridProps> {
91
94
  lazyReset: currentConfig.grid?.lazyReset,
92
95
  fitHeight: currentConfig.grid?.fitHeight,
93
96
  striped: currentConfig.grid?.striped,
97
+ autoBoxSizeOffset: currentConfig.grid?.autoBoxSizeOffset,
94
98
  };
95
99
  }
96
100