Browse Source

feat: table grid supports setting title and helpMessage (#4732)

Vben 5 months ago
parent
commit
6688a6b3c2

+ 5 - 1
apps/web-antd/src/adapter/vxe-table.ts

@@ -11,7 +11,10 @@ setupVbenVxeTable({
     vxeUI.setConfig({
       grid: {
         align: 'center',
-        border: true,
+        border: false,
+        columnConfig: {
+          resizable: true,
+        },
         minHeight: 180,
         proxyConfig: {
           autoLoad: true,
@@ -24,6 +27,7 @@ setupVbenVxeTable({
           showResponseMsg: false,
         },
         round: true,
+        showOverflow: true,
         size: 'small',
       },
     });

+ 5 - 1
apps/web-ele/src/adapter/vxe-table.ts

@@ -11,7 +11,10 @@ setupVbenVxeTable({
     vxeUI.setConfig({
       grid: {
         align: 'center',
-        border: true,
+        border: false,
+        columnConfig: {
+          resizable: true,
+        },
         minHeight: 180,
         proxyConfig: {
           autoLoad: true,
@@ -24,6 +27,7 @@ setupVbenVxeTable({
           showResponseMsg: false,
         },
         round: true,
+        showOverflow: true,
         size: 'small',
       },
     });

+ 5 - 1
apps/web-naive/src/adapter/vxe-table.ts

@@ -11,7 +11,10 @@ setupVbenVxeTable({
     vxeUI.setConfig({
       grid: {
         align: 'center',
-        border: true,
+        border: false,
+        columnConfig: {
+          resizable: true,
+        },
         minHeight: 180,
         proxyConfig: {
           autoLoad: true,
@@ -24,6 +27,7 @@ setupVbenVxeTable({
           showResponseMsg: false,
         },
         round: true,
+        showOverflow: true,
         size: 'small',
       },
     });

+ 0 - 3
internal/node-utils/package.json

@@ -40,8 +40,5 @@
     "pkg-types": "catalog:",
     "prettier": "catalog:",
     "rimraf": "catalog:"
-  },
-  "devDependencies": {
-    "@types/chalk": "catalog:"
   }
 }

+ 1 - 1
packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts

@@ -29,7 +29,7 @@ export class ModalApi {
     } = options;
 
     const defaultState: ModalState = {
-      bordered: false,
+      bordered: true,
       centered: false,
       class: '',
       closeOnClickModal: true,

+ 7 - 1
packages/@core/ui-kit/popup-ui/src/modal/modal.vue

@@ -258,7 +258,13 @@ function handleFocusOutside(e: Event) {
         v-if="showFooter"
         ref="footerRef"
         :class="
-          cn('flex-row items-center justify-end border-t p-2', footerClass)
+          cn(
+            'flex-row items-center justify-end p-2',
+            {
+              'border-t': bordered,
+            },
+            footerClass,
+          )
         "
       >
         <slot name="prepend-footer"></slot>

+ 1 - 0
packages/effects/plugins/src/vxe-table/theme.css

@@ -8,6 +8,7 @@
 
   /* base */
   --vxe-ui-base-popup-border-color: hsl(var(--border));
+  --vxe-ui-input-disabled-color: hsl(var(--border) / 60%);
 
   /* --vxe-ui-base-popup-box-shadow: 0px 12px 30px 8px rgb(0 0 0 / 50%); */
 

+ 8 - 0
packages/effects/plugins/src/vxe-table/types.ts

@@ -19,6 +19,14 @@ export interface VxePaginationInfo {
 }
 
 export interface VxeGridProps {
+  /**
+   * 标题
+   */
+  tableTitle?: string;
+  /**
+   * 标题帮助
+   */
+  tableTitleHelp?: string;
   /**
    * 组件class
    */

+ 51 - 16
packages/effects/plugins/src/vxe-table/use-vxe-grid.vue

@@ -22,7 +22,7 @@ import { EmptyIcon } from '@vben/icons';
 import { $t } from '@vben/locales';
 import { usePreferences } from '@vben/preferences';
 import { cloneDeep, cn, mergeWithArrayOverride } from '@vben/utils';
-import { VbenLoading } from '@vben-core/shadcn-ui';
+import { VbenHelpTooltip, VbenLoading } from '@vben-core/shadcn-ui';
 
 import { VxeGrid, VxeUI } from 'vxe-table';
 
@@ -51,6 +51,8 @@ const {
   gridClass,
   gridEvents,
   formOptions,
+  tableTitle,
+  tableTitleHelp,
 } = usePriorityValues(props, state);
 
 const { isMobile } = usePreferences();
@@ -79,31 +81,45 @@ const [Form, formApi] = useTableForm({
   wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
 });
 
+const showTableTitle = computed(() => {
+  return !!slots.tableTitle?.() || tableTitle.value;
+});
+
 const showToolbar = computed(() => {
-  return !!slots['toolbar-actions']?.() || !!slots['toolbar-tools']?.();
+  return (
+    !!slots['toolbar-actions']?.() ||
+    !!slots['toolbar-tools']?.() ||
+    showTableTitle.value
+  );
 });
 
-const options = computed(() => {
+const toolbarOptions = computed(() => {
   const slotActions = slots['toolbar-actions']?.();
   const slotTools = slots['toolbar-tools']?.();
+  if (!showToolbar.value) {
+    return {};
+  }
+  // 强制使用固定的toolbar配置,不允许用户自定义
+  // 减少配置的复杂度,以及后续维护的成本
+  return {
+    toolbarConfig: {
+      slots: {
+        ...(slotActions || showTableTitle.value
+          ? { buttons: 'toolbar-actions' }
+          : {}),
+        ...(slotTools ? { tools: 'toolbar-tools' } : {}),
+      },
+    },
+  };
+});
 
+const options = computed(() => {
   const globalGridConfig = VxeUI?.getConfig()?.grid ?? {};
 
-  const forceUseToolbarOptions = showToolbar.value
-    ? {
-        toolbarConfig: {
-          slots: {
-            ...(slotActions ? { buttons: 'toolbar-actions' } : {}),
-            ...(slotTools ? { tools: 'toolbar-tools' } : {}),
-          },
-        },
-      }
-    : {};
-
   const mergedOptions: VxeTableGridProps = cloneDeep(
     mergeWithArrayOverride(
       {},
-      forceUseToolbarOptions,
+      toolbarOptions.value,
       toRaw(gridOptions.value),
       globalGridConfig,
     ),
@@ -164,7 +180,7 @@ const delegatedSlots = computed(() => {
   const resultSlots: string[] = [];
 
   for (const key of Object.keys(slots)) {
-    if (!['empty', 'form', 'loading'].includes(key)) {
+    if (!['empty', 'form', 'loading', 'toolbar-actions'].includes(key)) {
       resultSlots.push(key);
     }
   }
@@ -209,6 +225,7 @@ async function init() {
   extendProxyOptions(props.api, defaultGridOptions, () => formApi.form.values);
 }
 
+// formOptions支持响应式
 watch(
   formOptions,
   () => {
@@ -251,6 +268,20 @@ onMounted(() => {
       v-bind="options"
       v-on="events"
     >
+      <!-- 左侧操作区域或者title -->
+      <template v-if="showToolbar" #toolbar-actions="slotProps">
+        <slot v-if="showTableTitle" name="table-title">
+          <div class="mr-1 pl-1 text-[1rem]">
+            {{ tableTitle }}
+            <VbenHelpTooltip v-if="tableTitleHelp" trigger-class="pb-1">
+              {{ tableTitleHelp }}
+            </VbenHelpTooltip>
+          </div>
+        </slot>
+        <slot name="toolbar-actions" v-bind="slotProps"> </slot>
+      </template>
+
+      <!-- 继承默认的slot -->
       <template
         v-for="slotName in delegatedSlots"
         :key="slotName"
@@ -258,6 +289,8 @@ onMounted(() => {
       >
         <slot :name="slotName" v-bind="slotProps"></slot>
       </template>
+
+      <!-- form表单 -->
       <template #form>
         <div v-if="formOptions" class="relative rounded py-3 pb-4">
           <slot name="form">
@@ -291,11 +324,13 @@ onMounted(() => {
           ></div>
         </div>
       </template>
+      <!-- loading -->
       <template #loading>
         <slot name="loading">
           <VbenLoading :spinning="true" />
         </slot>
       </template>
+      <!-- 统一控状态 -->
       <template #empty>
         <slot name="empty">
           <EmptyIcon class="mx-auto" />

+ 5 - 1
playground/src/adapter/vxe-table.ts

@@ -11,7 +11,10 @@ setupVbenVxeTable({
     vxeUI.setConfig({
       grid: {
         align: 'center',
-        border: true,
+        border: false,
+        columnConfig: {
+          resizable: true,
+        },
         minHeight: 180,
         proxyConfig: {
           autoLoad: true,
@@ -24,6 +27,7 @@ setupVbenVxeTable({
           showResponseMsg: false,
         },
         round: true,
+        showOverflow: true,
         size: 'small',
       },
     });

+ 3 - 3
playground/src/views/examples/vxe-table/basic.vue

@@ -76,10 +76,10 @@ function changeLoading() {
     <template #extra>
       <DocButton path="/components/common-ui/vben-vxe-table" />
     </template>
-    <Grid>
-      <template #toolbar-actions>
+    <Grid table-title="基础列表" table-title-help="提示">
+      <!-- <template #toolbar-actions>
         <Button class="mr-2" type="primary">左侧插槽</Button>
-      </template>
+      </template> -->
       <template #toolbar-tools>
         <Button class="mr-2" type="primary" @click="changeBorder">
           {{ showBorder ? '隐藏' : '显示' }}边框

+ 1 - 1
playground/src/views/examples/vxe-table/remote.vue

@@ -51,7 +51,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ gridOptions });
 
 <template>
   <Page auto-content-height>
-    <Grid>
+    <Grid table-title="数据列表" table-title-help="提示">
       <template #toolbar-tools>
         <Button class="mr-2" type="primary" @click="() => gridApi.query()">
           刷新当前页面

+ 1 - 1
playground/src/views/examples/vxe-table/tree.vue

@@ -50,7 +50,7 @@ const collapseAll = () => {
 
 <template>
   <Page>
-    <Grid>
+    <Grid table-title="数据列表" table-title-help="提示">
       <template #toolbar-tools>
         <Button class="mr-2" type="primary" @click="expandAll">
           展开全部

File diff suppressed because it is too large
+ 230 - 177
pnpm-lock.yaml


+ 12 - 13
pnpm-workspace.yaml

@@ -22,7 +22,7 @@ catalog:
   '@ctrl/tinycolor': ^4.1.0
   '@eslint/js': ^9.13.0
   '@faker-js/faker': ^9.0.3
-  '@iconify/json': ^2.2.262
+  '@iconify/json': ^2.2.263
   '@iconify/tailwind': ^1.1.3
   '@iconify/vue': ^4.1.2
   '@intlify/core-base': ^10.0.4
@@ -35,22 +35,21 @@ catalog:
   '@stylistic/stylelint-plugin': ^3.1.1
   '@tailwindcss/nesting': 0.0.0-insiders.565cd3e
   '@tailwindcss/typography': ^0.5.15
-  '@tanstack/vue-query': ^5.59.13
+  '@tanstack/vue-query': ^5.59.16
   '@tanstack/vue-store': ^0.5.6
-  '@types/archiver': ^6.0.2
-  '@types/chalk': ^2.2.0
+  '@types/archiver': ^6.0.3
   '@types/eslint': ^9.6.1
   '@types/html-minifier-terser': ^7.0.2
   '@types/jsonwebtoken': ^9.0.7
   '@types/lodash.clonedeep': ^4.5.9
-  '@types/node': ^22.7.8
+  '@types/node': ^22.7.9
   '@types/nprogress': ^0.2.3
   '@types/postcss-import': ^14.0.3
   '@types/qrcode': ^1.5.5
   '@types/sortablejs': ^1.15.8
   '@typescript-eslint/eslint-plugin': ^8.11.0
   '@typescript-eslint/parser': ^8.11.0
-  '@vee-validate/zod': ^4.14.3
+  '@vee-validate/zod': ^4.14.4
   '@vite-pwa/vitepress': ^0.5.3
   '@vitejs/plugin-vue': ^5.1.4
   '@vitejs/plugin-vue-jsx': ^4.0.1
@@ -127,11 +126,11 @@ catalog:
   postcss-antd-fixes: ^0.2.0
   postcss-html: ^1.7.0
   postcss-import: ^16.1.0
-  postcss-preset-env: ^10.0.7
+  postcss-preset-env: ^10.0.8
   postcss-scss: ^4.0.9
   prettier: ^3.3.3
   prettier-plugin-tailwindcss: ^0.6.8
-  publint: ^0.2.11
+  publint: ^0.2.12
   qrcode: ^1.5.4
   radix-vue: ^1.9.7
   resolve.exports: ^2.0.2
@@ -157,15 +156,15 @@ catalog:
   typescript: ^5.6.3
   unbuild: ^2.0.0
   unplugin-element-plus: ^0.8.0
-  vee-validate: ^4.14.3
-  vite: ^5.4.9
+  vee-validate: ^4.14.4
+  vite: ^5.4.10
   vite-plugin-compression: ^0.5.1
   vite-plugin-dts: 4.2.1
   vite-plugin-html: ^3.2.2
   vite-plugin-lazy-import: ^1.0.7
   vite-plugin-lib-inject-css: ^2.1.1
   vite-plugin-pwa: ^0.20.5
-  vite-plugin-vue-devtools: ^7.5.2
+  vite-plugin-vue-devtools: ^7.5.3
   vitepress: ^1.4.1
   vitepress-plugin-group-icons: ^1.3.0
   vitest: ^2.1.3
@@ -174,8 +173,8 @@ catalog:
   vue-i18n: ^10.0.4
   vue-router: ^4.4.5
   vue-tsc: ^2.1.6
-  vxe-pc-ui: ^4.2.26
-  vxe-table: ^4.7.93
+  vxe-pc-ui: ^4.2.28
+  vxe-table: ^4.7.94
   watermark-js-plus: ^1.5.7
   zod: ^3.23.8
   zod-defaults: ^0.1.3

Some files were not shown because too many files changed in this diff