chore: 升级 shadcn-vue 组件到v4最新版 (#7972)

* fix: useStore is deprecated

* chore: update deps

* feat: 升级shadcn-ui v4

* fix: workbench style

* feat: 升级shadcn-ui v4 step2

* feat: 升级shadcn-ui v4 step3

* chore: 升级shadcn v4

* fix: pagination

* fix: dark style

* fix: doc import

* feat: 增加详情组件,参考 antdv-next

* docs: descriptions docs

* docs: Browser Support

* feat: add table action

* feat: icon use vbenIcon

* fix: type error

* fix: dropdown popConfirm

* feat: 使用默认的文字交互

* feat: 优化渲染性能
This commit is contained in:
xingyu
2026-05-31 15:18:46 +08:00
committed by GitHub
parent 108d7ff335
commit 04fbb7a556
239 changed files with 6015 additions and 3205 deletions

View File

@@ -0,0 +1,102 @@
---
outline: deep
---
# Vben Descriptions
`Descriptions` displays a group of read-only fields, commonly used on detail pages and information previews. It is built on shadcn-ui with an API modeled after Ant Design Vue's Descriptions, supporting responsive columns, column spanning, borders, and vertical layout.
> If the documentation does not cover the details you need, please refer to the online examples.
::: info Before you start
The component supports two usages: data-driven via `items` (recommended), or declaring entries with the `VbenDescriptionsItem` child component. `items` takes precedence when both are provided. :::
## Basic Usage
Pass an array of fields via `items`, each with a `label` and `content`. Columns adapt to breakpoints by default (1 column on `xs`, 2 on `sm`, 3 on `md` and above).
<DemoPreview dir="demos/vben-descriptions/basic" />
## Bordered
Set `bordered` for a bordered style, combined with the `title` prop and the `#extra` slot (an action area on the right of the title).
<DemoPreview dir="demos/vben-descriptions/bordered" />
## Vertical Layout
Use `layout="vertical"` to place labels above their content.
<DemoPreview dir="demos/vben-descriptions/vertical" />
## Sizes
Use `size` to switch between `small`, `middle`, and `large`.
<DemoPreview dir="demos/vben-descriptions/size" />
## Span & Responsive
Set `span` on an item to span multiple columns; `'filled'` fills the remaining space of the current row. `column` accepts a breakpoint-keyed object for responsive columns.
<DemoPreview dir="demos/vben-descriptions/span" />
## Child Component Usage
When `items` is omitted, declare entries with `VbenDescriptionsItem` in the default slot. Content can be customized via the default slot or the `#content` slot.
<DemoPreview dir="demos/vben-descriptions/custom" />
## API
### Descriptions Props
| Prop | Description | Type | Default |
| --- | --- | --- | --- |
| items | Data-driven entries; reads the default slot when omitted | `DescriptionsItemType[]` | - |
| bordered | Whether to show borders | `boolean` | `false` |
| column | Columns per row, supports breakpoint config | `number \| Partial<Record<Breakpoint, number>>` | `{ xs: 1, sm: 2, md: 3, xxxl: 4 }` |
| layout | Layout direction | `'horizontal' \| 'vertical'` | `'horizontal'` |
| size | Size | `'small' \| 'middle' \| 'large'` | `'middle'` |
| colon | Show colon (only for non-bordered horizontal layout) | `boolean` | `true` |
| title | Title | `string` | - |
| extra | Action area on the right of the title | `string` | - |
| labelStyle | Shared label style | `CSSProperties` | - |
| contentStyle | Shared content style | `CSSProperties` | - |
| class | Custom class for the root node | `string` | - |
### Descriptions Slots
| Slot | Description |
| ------- | ------------------------------------- |
| title | Custom title |
| extra | Custom action area beside the title |
| default | Place `VbenDescriptionsItem` children |
### DescriptionsItem
Each entry in `items`, or the props of the `VbenDescriptionsItem` child component.
| Prop | Description | Type | Default |
| --- | --- | --- | --- |
| label | Label | `string \| number \| (() => VNode) \| Component` | - |
| content | Content | `string \| number \| (() => VNode) \| Component` | - |
| span | Columns to span, `'filled'` fills the rest of the row | `number \| 'filled' \| Partial<Record<Breakpoint, number>>` | `1` |
| labelStyle | Label style | `CSSProperties` | - |
| contentStyle | Content style | `CSSProperties` | - |
| key | Unique key | `string \| number` | - |
### DescriptionsItem Slots
Available only for the child component usage.
| Slot | Description |
| ------- | --------------------------------- |
| default | Content (equivalent to `content`) |
| content | Custom content |
| label | Custom label |
::: tip Breakpoint
The responsive `Breakpoint` is one of `'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'xxxl'`, with pixel values aligned with Ant Design (`sm` 576, `md` 768, `lg` 992, `xl` 1200, `xxl` 1600, `xxxl` 2000). :::

View File

@@ -0,0 +1,165 @@
---
outline: deep
---
# Vben TableAction
`TableAction` renders a group of action buttons for table operation columns, inspired by the TableAction component from vben2. Built on shadcn-ui, it supports permission control, popconfirm, tooltips, a "more" dropdown, and dividers, and can be reused inside or outside tables.
> If the documentation does not cover the details you need, please refer to the online examples.
::: info Before you start
The component carries no business logic (it does not read the permission store directly); permissions are handled by injecting `hasPermission`, keeping the core layer decoupled and reusable across frameworks. Inside vxe-table, the recommended approach is to render it via a column slot (`slots: { default: 'action' }`) on the page, without changing the table's original rendering mechanism. :::
## Basic Usage
Pass an array of action items via `actions`, each with `text`, `onClick`, etc. `danger` marks destructive actions, and `divider` shows separators between buttons.
<DemoPreview dir="demos/vben-table-action/basic" />
## Tooltip
Add a tooltip to an action via `tooltip`, accepting a string or a `{ content, side }` object.
<DemoPreview dir="demos/vben-table-action/tooltip" />
## PopConfirm
Use `popConfirm` to require confirmation before the action runs, commonly used for destructive actions like delete.
<DemoPreview dir="demos/vben-table-action/popconfirm" />
## More Dropdown
Use `dropdownActions` to collapse secondary actions into a "more" dropdown. `moreText` customizes the button label.
<DemoPreview dir="demos/vben-table-action/dropdown" />
## Permission Control
Set an `auth` code on an action and inject a `hasPermission` resolver; actions without permission are hidden.
<DemoPreview dir="demos/vben-table-action/permission" />
## Usage with vxe-table
Without changing vxe-table's rendering mechanism, declare a slot in the column config and render it on the page.
::: tip Recommended: use the adapter-wrapped version The project's `#/adapter/vxe-table` re-wraps `VbenTableAction` and injects `hasPermission` internally (based on `useAccess().hasAccessByCodes`). So when you import it from the adapter, **you no longer need to pass `:has-permission`** — just declare permission codes via the `auth` field of each action. :::
```ts
// data.ts — declare a slot in the column config
{
align: 'center',
field: 'operation',
fixed: 'right',
slots: { default: 'action' },
title: $t('system.user.operation'),
width: 180,
}
```
```vue
<!-- list.vue import from the adapter; permission is auto-injected, no has-permission needed -->
<script setup lang="ts">
import { VbenTableAction } from '#/adapter/vxe-table';
</script>
<template>
<Grid>
<template #action="{ row }">
<template #action="{ row }">
<VbenTableAction
:actions="[
{
text: $t('common.detail'),
icon: 'lucide:eye',
onClick: () => onDetail(row),
},
{
text: $t('common.edit'),
icon: 'lucide:edit',
onClick: () => onEdit(row),
},
]"
:dropdown-actions="[
{
text: $t('common.delete'),
icon: 'lucide:trash-2',
danger: true,
onClick: () => onDelete(row),
auth: ['AC_100100'],
},
]"
align="center"
/>
</template>
</template>
</Grid>
</template>
```
If you import the core component directly from `@vben/common-ui` (without going through the adapter), the component carries no business logic and you need to inject `hasPermission` yourself:
```vue
<script setup lang="ts">
import { useAccess } from '@vben/access';
import { VbenTableAction } from '@vben/common-ui';
const { hasAccessByCodes } = useAccess();
function hasPermission(auth?: string | string[]) {
if (!auth) return true;
return hasAccessByCodes(Array.isArray(auth) ? auth : [auth]);
}
</script>
<template>
<VbenTableAction
v-bind="useActions(row, onActionClick)"
:has-permission="hasPermission"
align="center"
/>
</template>
```
## API
### TableAction Props
| Prop | Description | Type | Default |
| --- | --- | --- | --- |
| actions | Main action buttons | `ActionItem[]` | `[]` |
| dropdownActions | Actions inside the "more" dropdown | `ActionItem[]` | `[]` |
| align | Alignment | `'start' \| 'center' \| 'end'` | `'end'` |
| divider | Whether to show separators between buttons | `boolean` | `false` |
| moreText | Label for the "more" button (shown beside the icon) | `string` | - |
| hasPermission | Permission resolver; returning `false` hides the action with that `auth` (auto-injected when imported from `#/adapter/vxe-table`, no need to pass manually) | `(auth?: string \| string[]) => boolean` | - |
| class | Custom class for the root node | `string` | - |
### ActionItem
| Prop | Description | Type | Default |
| --- | --- | --- | --- |
| text | Button text | `string` | - |
| icon | Icon component | `string` \| `VbenIcon` | - |
| onClick | Click callback | `() => void` | - |
| auth | Permission code, filtered by `hasPermission` | `string \| string[]` | - |
| ifShow | Whether to show | `boolean \| (() => boolean)` | `true` |
| disabled | Whether disabled | `boolean` | `false` |
| loading | Loading state | `boolean` | `false` |
| danger | Destructive action (red text) | `boolean` | `false` |
| tooltip | Tooltip | `string \| { content: string; side?: 'top' \| 'bottom' \| 'left' \| 'right' }` | - |
| popConfirm | PopConfirm | `TableActionPopConfirm` | - |
| variant | Button variant | `ButtonVariants['variant']` | `'link'` |
| size | Button size | `ButtonVariants['size']` | `'sm'` |
| key | Unique key | `string \| number` | - |
### TableActionPopConfirm
| Prop | Description | Type | Default |
| --- | --- | --- | --- |
| title | Confirm title | `string` | `'Are you sure?'` |
| okText | Confirm button text | `string` | `'OK'` |
| cancelText | Cancel button text | `string` | `'Cancel'` |
| confirm | Confirm callback; falls back to `action.onClick` if omitted | `() => void` | - |