Explorar o código

docs(@vben/docs): sync component docs with current APIs

xingyu4j hai 3 meses
pai
achega
6b3bcee582

+ 76 - 5
docs/.vitepress/config/en.mts

@@ -42,6 +42,10 @@ export const en = defineConfig({
         base: '/en/commercial/',
         items: sidebarCommercial(),
       },
+      '/en/components/': {
+        base: '/en/components/',
+        items: sidebarComponents(),
+      },
       '/en/guide/': { base: '/en/guide/', items: sidebarGuide() },
     },
   },
@@ -63,6 +67,11 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] {
         },
         { link: 'introduction/quick-start', text: 'Quick Start' },
         { link: 'introduction/thin', text: 'Lite Version' },
+        {
+          base: '/',
+          link: 'components/introduction',
+          text: 'Components',
+        },
       ],
     },
     {
@@ -132,6 +141,68 @@ function sidebarCommercial(): DefaultTheme.SidebarItem[] {
   ];
 }
 
+function sidebarComponents(): DefaultTheme.SidebarItem[] {
+  return [
+    {
+      text: 'Components',
+      items: [
+        {
+          link: 'introduction',
+          text: 'Introduction',
+        },
+      ],
+    },
+    {
+      collapsed: false,
+      text: 'Layout UI',
+      items: [
+        {
+          link: 'layout-ui/page',
+          text: 'Page',
+        },
+      ],
+    },
+    {
+      collapsed: false,
+      text: 'Common UI',
+      items: [
+        {
+          link: 'common-ui/vben-api-component',
+          text: 'ApiComponent',
+        },
+        {
+          link: 'common-ui/vben-alert',
+          text: 'Alert',
+        },
+        {
+          link: 'common-ui/vben-modal',
+          text: 'Modal',
+        },
+        {
+          link: 'common-ui/vben-drawer',
+          text: 'Drawer',
+        },
+        {
+          link: 'common-ui/vben-form',
+          text: 'Form',
+        },
+        {
+          link: 'common-ui/vben-vxe-table',
+          text: 'Vxe Table',
+        },
+        {
+          link: 'common-ui/vben-count-to-animator',
+          text: 'CountToAnimator',
+        },
+        {
+          link: 'common-ui/vben-ellipsis-text',
+          text: 'EllipsisText',
+        },
+      ],
+    },
+  ];
+}
+
 function nav(): DefaultTheme.NavItem[] {
   return [
     {
@@ -143,11 +214,11 @@ function nav(): DefaultTheme.NavItem[] {
           link: '/en/guide/introduction/vben',
           text: 'Guide',
         },
-        // {
-        //   activeMatch: '^/en/components/',
-        //   link: '/en/components/introduction',
-        //   text: 'Components',
-        // },
+        {
+          activeMatch: '^/en/components/',
+          link: '/en/components/introduction',
+          text: 'Components',
+        },
         {
           text: 'Historical Versions',
           items: [

+ 2 - 0
docs/src/_env/adapter/form.ts

@@ -10,7 +10,9 @@ import { $t } from '@vben/locales';
 
 import { initComponentAdapter } from './component';
 
+// oxlint-disable-next-line typescript/no-floating-promises
 initComponentAdapter();
+
 setupVbenForm<ComponentType>({
   config: {
     baseModelPropName: 'value',

+ 18 - 69
docs/src/components/common-ui/vben-alert.md

@@ -4,132 +4,90 @@ outline: deep
 
 # Vben Alert 轻量提示框
 
-框架提供的一些用于轻量提示的弹窗,仅使用js代码即可快速动态创建提示而不需要在template写任何代码
+`Alert` 提供了一组纯 JavaScript 调用的轻量提示框能力,适合快速创建 `alert`、`confirm`、`prompt` 这类简单交互
 
-::: info 用场景
+::: info 用场景
 
-Alert提供的功能与Modal类似,但只适用于简单应用场景。例如临时性、动态地弹出模态确认框、输入框等。如果对弹窗有更复杂的需求,请使用VbenModal
-
-:::
+`Alert` 与 `Modal` 的能力有部分重叠,但更适合临时确认、简单提示和轻量输入场景。复杂弹窗仍然建议使用 `Vben Modal`。:::
 
 ::: tip 注意
 
-Alert提供的快捷方法alert、confirm、prompt动态创建的弹窗在已打开的情况下,不支持HMR(热更新),代码变更后需要关闭这些弹窗后重新打开。
-
-:::
-
-::: tip README
-
-下方示例代码中的,存在一些主题色未适配、样式缺失的问题,这些问题只在文档内会出现,实际使用并不会有这些问题,可忽略,不必纠结。
-
-:::
+通过 `alert`、`confirm`、`prompt` 动态创建的弹窗,在已经打开的情况下不支持 HMR 热更新。修改相关代码后,需要关闭后重新打开。:::
 
 ## 基础用法
 
-使用 `alert` 创建只有一个确认按钮的提示框。
+使用 `alert` 创建只有确认按钮的提示框。
 
 <DemoPreview dir="demos/vben-alert/alert" />
 
-使用 `confirm` 创建确认和取消按钮的提示框。
+使用 `confirm` 创建带确认和取消按钮的提示框。
 
 <DemoPreview dir="demos/vben-alert/confirm" />
 
-使用 `prompt` 创建有确认和取消按钮、接受用户输入的提示框。
+使用 `prompt` 创建可接收用户输入的提示框。
 
 <DemoPreview dir="demos/vben-alert/prompt" />
 
 ## useAlertContext
 
-当弹窗的content、footer、icon使用自定义组件时,在这些组件中可以使用 `useAlertContext` 获取当前弹窗的上下文对象,用来主动控制弹窗
+当 `content`、`footer` 或 `icon` 使用的是自定义组件时,可以在这些组件内部通过 `useAlertContext()` 获取当前弹窗上下文,并主动触发确认或取消
 
 ::: tip 注意
 
-`useAlertContext`只能用在setup或者函数式组件中。
-
-:::
+`useAlertContext` 只能在 `setup` 或函数式组件中使用。:::
 
 ### Methods
 
-| 方法      | 描述               | 类型     | 版本要求 |
-| --------- | ------------------ | -------- | -------- |
-| doConfirm | 调用弹窗的确认操作 | ()=>void | >5.5.4   |
-| doCancel  | 调用弹窗的取消操作 | ()=>void | >5.5.4   |
+| 方法      | 描述                   | 类型         | 版本要求 |
+| --------- | ---------------------- | ------------ | -------- |
+| doConfirm | 触发当前弹窗的确认操作 | `() => void` | `>5.5.4` |
+| doCancel  | 触发当前弹窗的取消操作 | `() => void` | `>5.5.4` |
 
 ## 类型说明
 
 ```ts
-/** 预置的图标类型 */
 export type IconType = 'error' | 'info' | 'question' | 'success' | 'warning';
 
 export type BeforeCloseScope = {
-  /** 是否为点击确认按钮触发的关闭 */
   isConfirm: boolean;
 };
 
-/**
- * alert 属性
- */
 export type AlertProps = {
-  /** 关闭前的回调,如果返回false,则终止关闭 */
   beforeClose?: (
     scope: BeforeCloseScope,
   ) => boolean | Promise<boolean | undefined> | undefined;
-  /** 边框 */
   bordered?: boolean;
-  /** 按钮对齐方式 */
   buttonAlign?: 'center' | 'end' | 'start';
-  /** 取消按钮的标题 */
   cancelText?: string;
-  /** 是否居中显示 */
   centered?: boolean;
-  /** 确认按钮的标题 */
   confirmText?: string;
-  /** 弹窗容器的额外样式 */
   containerClass?: string;
-  /** 弹窗提示内容 */
   content: Component | string;
-  /** 弹窗内容的额外样式 */
   contentClass?: string;
-  /** 执行beforeClose回调期间,在内容区域显示一个loading遮罩*/
   contentMasking?: boolean;
-  /** 弹窗底部内容(与按钮在同一个容器中) */
   footer?: Component | string;
-  /** 弹窗的图标(在标题的前面) */
   icon?: Component | IconType;
-  /**
-   * 弹窗遮罩模糊效果
-   */
   overlayBlur?: number;
-  /** 是否显示取消按钮 */
   showCancel?: boolean;
-  /** 弹窗标题 */
   title?: string;
 };
 
-/** prompt 属性 */
 export type PromptProps<T = any> = {
-  /** 关闭前的回调,如果返回false,则终止关闭 */
   beforeClose?: (scope: {
     isConfirm: boolean;
     value: T | undefined;
   }) => boolean | Promise<boolean | undefined> | undefined;
-  /** 用于接受用户输入的组件 */
   component?: Component;
-  /** 输入组件的属性 */
   componentProps?: Recordable<any>;
-  /** 输入组件的插槽 */
-  componentSlots?: Recordable<Component>;
-  /** 默认值 */
+  componentSlots?:
+    | (() => any)
+    | Recordable<unknown>
+    | VNode
+    | VNodeArrayChildren;
   defaultValue?: T;
-  /** 输入组件的值属性名 */
   modelPropName?: string;
 } & Omit<AlertProps, 'beforeClose'>;
 
-/**
- * 函数签名
- * alert和confirm的函数签名相同。
- * confirm默认会显示取消按钮,而alert默认只有一个按钮
- *  */
 export function alert(options: AlertProps): Promise<void>;
 export function alert(
   message: string,
@@ -141,19 +99,10 @@ export function alert(
   options?: Partial<AlertProps>,
 ): Promise<void>;
 
-/**
- * 弹出输入框的函数签名。
- * beforeClose的参数会传入用户当前输入的值
- * component指定接受用户输入的组件,默认为Input
- * componentProps 为输入组件设置的属性数据
- * defaultValue 默认的值
- * modelPropName 输入组件的值属性名称。默认为modelValue
- */
 export async function prompt<T = any>(
   options: Omit<AlertProps, 'beforeClose'> & {
     beforeClose?: (
       scope: BeforeCloseScope & {
-        /** 输入组件的当前值 */
         value: T;
       },
     ) => boolean | Promise<boolean | undefined> | undefined;

+ 1 - 1
docs/src/components/common-ui/vben-api-component.md

@@ -14,7 +14,7 @@ outline: deep
 
 ## 基础用法
 
-通过 `component` 传入其它组件的定义,并配置相关的其它属性(主要是一些名称映射)。包装组件将通过`api`获取数据(`beforerFetch`、`afterFetch`将分别在`api`运行前、运行后被调用),使用`resultField`从中提取数组,使用`valueField`、`labelField`等来从数据中提取value和label(如果提供了`childrenField`,会将其作为树形结构递归处理每一级数据),之后将处理好的数据通过`optionsPropName`指定的属性传递给目标组件。
+通过 `component` 传入其它组件的定义,并配置相关的其它属性(主要是一些名称映射)。包装组件将通过 `api` 获取数据(`beforeFetch`、`afterFetch` 将分别在 `api` 运行前、运行后被调用),使用 `resultField` 从中提取数组,使用 `valueField`、`labelField` 等来从数据中提取 value  label(如果提供了 `childrenField`,会将其作为树形结构递归处理每一级数据),之后将处理好的数据通过 `optionsPropName` 指定的属性传递给目标组件。
 
 ::: details 包装级联选择器,点击下拉时开始加载远程数据
 

+ 29 - 31
docs/src/components/common-ui/vben-count-to-animator.md

@@ -4,56 +4,54 @@ outline: deep
 
 # Vben CountToAnimator 数字动画
 
-框架提供的数字动画组件,支持数字动画效果。
+`CountToAnimator` 用于展示数字滚动动画效果。
 
-> 如果文档内没有参数说明,可以尝试在在线示例内寻找
+> 如果文档内没有覆盖到你需要的细节,可以结合在线示例一起查看。
 
 ::: info 写在前面
 
-如果你觉得现有组件的封装不够理想,或者不完全符合你的需求,大可以直接使用原生组件,亦或亲手封装一个适合的组件。框架提供的组件并非束缚,使用与否,完全取决于你的需求与自由。
-
-:::
+这是一个轻量数字动画组件。如果你需要完全不同的过渡控制方式,也可以直接使用原生动画方案或自行封装。:::
 
 ## 基础用法
 
-通过 `start-val` 和 `end-val`设置数字动画的开始值和结束值, 持续时间`3000`ms
+通过 `start-val` 和 `end-val` 设置数字动画的起始值和结束值,配合 `duration` 控制动画时长
 
 <DemoPreview dir="demos/vben-count-to-animator/basic" />
 
-## 自定义前缀分隔符
+## 自定义前缀分隔符
 
-通过 `prefix` 和 `separator` 设置数字动画的前缀和分隔符
+通过 `prefix`、`suffix`、`separator` 和 `decimal` 可以控制展示格式
 
 <DemoPreview dir="demos/vben-count-to-animator/custom" />
 
 ### Props
 
-| 属性名     | 描述           | 类型      | 默认值   |
-| ---------- | -------------- | --------- | -------- |
-| startVal   | 起始值         | `number`  | `0`      |
-| endVal     | 结束值         | `number`  | `2021`   |
-| duration   | 动画持续时间   | `number`  | `1500`   |
-| autoplay   | 自动执行       | `boolean` | `true`   |
-| prefix     | 前缀           | `string`  | -        |
-| suffix     | 后缀           | `string`  | -        |
-| separator  | 分隔符         | `string`  | `,`      |
-| color      | 字体颜色       | `string`  | -        |
-| useEasing  | 是否开启动画   | `boolean` | `true`   |
-| transition | 动画效果       | `string`  | `linear` |
-| decimals   | 保留小数点位数 | `number`  | `0`      |
+| 属性名 | 描述 | 类型 | 默认值 |
+| --- | --- | --- | --- |
+| startVal | 起始值 | `number` | `0` |
+| endVal | 结束值 | `number` | `2021` |
+| duration | 动画持续时间 | `number` | `1500` |
+| autoplay | 是否自动播放 | `boolean` | `true` |
+| prefix | 前缀 | `string` | `''` |
+| suffix | 后缀 | `string` | `''` |
+| separator | 千分位分隔符 | `string` | `','` |
+| decimal | 小数点分隔符 | `string` | `'.'` |
+| color | 文本颜色 | `string` | `''` |
+| useEasing | 是否启用过渡预设 | `boolean` | `true` |
+| transition | 过渡预设名称 | `keyof typeof TransitionPresets` | `'linear'` |
+| decimals | 保留小数位数 | `number` | `0` |
 
 ### Events
 
-| 事件名         | 描述           | 类型           |
-| -------------- | -------------- | -------------- |
-| started        | 动画开始     | `()=>void`     |
-| finished       | 动画结束     | `()=>void`     |
-| ~~onStarted~~  | ~~动画已开始~~ | ~~`()=>void`~~ |
-| ~~onFinished~~ | ~~动画已结束~~ | ~~`()=>void`~~ |
+| 事件名         | 描述                          | 类型             |
+| -------------- | ----------------------------- | ---------------- |
+| started        | 动画开始时触发                | `() => void`     |
+| finished       | 动画结束时触发                | `() => void`     |
+| ~~onStarted~~  | ~~已废弃,请改用 `started`~~  | ~~`() => void`~~ |
+| ~~onFinished~~ | ~~已废弃,请改用 `finished`~~ | ~~`() => void`~~ |
 
 ### Methods
 
-| 方法名 | 描述         | 类型       |
-| ------ | ------------ | ---------- |
-| start  | 开始执行动画 | `()=>void` |
-| reset  | 重置         | `()=>void` |
+| 方法名 | 描述                             | 类型         |
+| ------ | -------------------------------- | ------------ |
+| reset  | 重置为 `startVal` 并重新执行动画 | `() => void` |

+ 3 - 3
docs/src/components/common-ui/vben-drawer.md

@@ -55,7 +55,7 @@ Drawer 内的内容一般业务中,会比较复杂,所以我们可以将 dra
 - `VbenDrawer` 组件对于参数的处理优先级是 `slot` > `props` > `state`(通过api更新的状态以及useVbenDrawer参数)。如果你已经传入了 `slot` 或者 `props`,那么 `setState` 将不会生效,这种情况下你可以通过 `slot` 或者 `props` 来更新状态。
 - 如果你使用到了 `connectedComponent` 参数,那么会存在 2 个`useVbenDrawer`, 此时,如果同时设置了相同的参数,那么以内部为准(也就是没有设置 connectedComponent 的代码)。比如 同时设置了 `onConfirm`,那么以内部的 `onConfirm` 为准。`onOpenChange`事件除外,内外都会触发。
 - 使用了`connectedComponent`参数时,可以配置`destroyOnClose`属性来决定当关闭弹窗时,是否要销毁`connectedComponent`组件(重新创建`connectedComponent`组件,这将会把其内部所有的变量、状态、数据等恢复到初始状态。)。
-- 如果抽屉的默认行为不符合你的预期,可以在`src\bootstrap.ts`中修改`setDefaultDrawerProps`的参数来设置默认的属性,如默认隐藏全屏按钮,修改默认ZIndex等。
+- 如果抽屉的默认行为不符合你的预期,可以在对应应用的 `apps/<app>/src/bootstrap.ts` 中修改 `setDefaultDrawerProps` 的参数来设置默认属性,例如修改默认 `zIndex` 等。
 
 :::
 
@@ -116,7 +116,7 @@ const [Drawer, drawerApi] = useVbenDrawer({
 
 | 事件名 | 描述 | 类型 | 版本限制 |
 | --- | --- | --- | --- |
-| onBeforeClose | 关闭前触发,返回 `false`则禁止关闭 | `()=>boolean` | --- |
+| onBeforeClose | 关闭前触发,返回 `false` 或 Promise reject 则禁止关闭 | `()=>Promise<boolean \| undefined>\|boolean\|undefined` | >5.5.2 支持 Promise |
 | onCancel | 点击取消按钮触发 | `()=>void` | --- |
 | onClosed | 关闭动画播放完毕时触发 | `()=>void` | >5.5.2 |
 | onConfirm | 点击确认按钮触发 | `()=>void` | --- |
@@ -140,7 +140,7 @@ const [Drawer, drawerApi] = useVbenDrawer({
 
 | 方法 | 描述 | 类型 | 版本限制 |
 | --- | --- | --- | --- |
-| setState | 动态设置弹窗状态属性 | `(((prev: ModalState) => Partial<ModalState>)\| Partial<ModalState>)=>drawerApi` |
+| setState | 动态设置抽屉状态属性 | `(((prev: DrawerState) => Partial<DrawerState>)\| Partial<DrawerState>)=>drawerApi` |
 | open | 打开弹窗 | `()=>void` | --- |
 | close | 关闭弹窗 | `()=>void` | --- |
 | setData | 设置共享数据 | `<T>(data:T)=>drawerApi` | --- |

+ 25 - 25
docs/src/components/common-ui/vben-ellipsis-text.md

@@ -4,31 +4,31 @@ outline: deep
 
 # Vben EllipsisText 省略文本
 
-框架提供的文本展示组件,可配置超长省略、tooltip提示、展开收起等功能
+`EllipsisText` 用于展示超长文本,支持省略、Tooltip 提示以及点击展开收起
 
-> 如果文档内没有参数说明,可以尝试在在线示例内寻找
+> 如果文档内没有覆盖到你需要的细节,可以结合在线示例一起查看。
 
 ## 基础用法
 
-通过默认插槽设置文本内容,`maxWidth`属性设置最大宽度。
+通过默认插槽提供文本内容,`maxWidth` 用于限制文本区域宽度。
 
 <DemoPreview dir="demos/vben-ellipsis-text/line" />
 
-## 可折叠文本
+## 可折叠文本
 
-通过`line`设置折叠后的行数,`expand`属性设置是否支持展开收起。
+通过 `line` 设置折叠后的最大行数,通过 `expand` 开启点击展开与收起。
 
 <DemoPreview dir="demos/vben-ellipsis-text/expand" />
 
 ## 自定义提示浮层
 
-通过名为`tooltip`的插槽定制提示信息
+通过 `tooltip` 插槽自定义提示内容
 
 <DemoPreview dir="demos/vben-ellipsis-text/tooltip" />
 
-## 自动显示 tooltip
+## 仅在省略时显示 Tooltip
 
-通过`tooltip-when-ellipsis`设置,仅在文本长度超出导致省略号出现时才触发 tooltip。
+通过 `tooltip-when-ellipsis` 控制仅在文本被截断时显示 Tooltip。
 
 <DemoPreview dir="demos/vben-ellipsis-text/auto-display" />
 
@@ -38,27 +38,27 @@ outline: deep
 
 | 属性名 | 描述 | 类型 | 默认值 |
 | --- | --- | --- | --- |
-| expand | 支持点击展开或收起 | `boolean` | `false` |
-| line | 文本最大行数 | `number` | `1` |
+| expand | 是否支持点击展开或收起 | `boolean` | `false` |
+| line | 文本最大显示行数 | `number` | `1` |
 | maxWidth | 文本区域最大宽度 | `number \| string` | `'100%'` |
-| placement | 提示浮层位置 | `'bottom'\|'left'\|'right'\|'top'` | `'top'` |
-| tooltip | 启用文本提示 | `boolean` | `true` |
-| tooltipWhenEllipsis | 内容超出,自动启用文本提示 | `boolean` | `false` |
-| ellipsisThreshold | 设置 tooltipWhenEllipsis 后才生效,文本截断检测的像素差异阈值,越大则判断越严格,如果碰见异常情况可以自己设置阈值 | `number` | `3` |
-| tooltipBackgroundColor | 提示文本的背景颜色 | `string` | - |
-| tooltipColor | 提示文本的颜色 | `string` | - |
-| tooltipFontSize | 提示文本的大小 | `string` | - |
-| tooltipMaxWidth | 提示浮层的最大宽度。如不设置则保持与文本宽度一致 | `number` | - |
-| tooltipOverlayStyle | 提示内容区域样式 | `CSSProperties` | `{ textAlign: 'justify' }` |
+| placement | 提示浮层位置 | `'bottom' \| 'left' \| 'right' \| 'top'` | `'top'` |
+| tooltip | 是否启用文本提示 | `boolean` | `true` |
+| tooltipWhenEllipsis | 是否仅在文本被截断时显示提示 | `boolean` | `false` |
+| ellipsisThreshold | 文本截断检测阈值,值越大判定越严格 | `number` | `3` |
+| tooltipBackgroundColor | 提示背景色 | `string` | `''` |
+| tooltipColor | 提示文字颜色 | `string` | `''` |
+| tooltipFontSize | 提示文字大小,单位 `px` | `number` | `14` |
+| tooltipMaxWidth | 提示内容最大宽度,单位 `px` | `number` | - |
+| tooltipOverlayStyle | 提示内容区域样式 | `CSSProperties` | `{ textAlign: 'justify' }` |
 
 ### Events
 
-| 事件名       | 描述         | 类型                       |
-| ------------ | ------------ | -------------------------- |
-| expandChange | 展开状态变 | `(isExpand:boolean)=>void` |
+| 事件名       | 描述               | 类型                          |
+| ------------ | ------------------ | ----------------------------- |
+| expandChange | 展开状态变化时触发 | `(isExpand: boolean) => void` |
 
 ### Slots
 
-| 插槽名  | 描述                             |
-| ------- | -------------------------------- |
-| tooltip | 启用文本提示时,用来定制提示内容 |
+| 插槽名  | 描述                               |
+| ------- | ---------------------------------- |
+| tooltip | 开启文本提示时,用于自定义提示内容 |

+ 30 - 50
docs/src/components/common-ui/vben-form.md

@@ -35,10 +35,15 @@ import type { ComponentType } from './component';
 import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
 import { $t } from '@vben/locales';
 
+import { initComponentAdapter } from './component';
+
+initComponentAdapter();
 setupVbenForm<ComponentType>({
   config: {
     // ant design vue组件库默认都是 v-model:value
     baseModelPropName: 'value',
+    // 一些组件库空值为 null,重置表单时需要和实际组件行为保持一致
+    emptyStateValue: null,
     // 一些组件是 v-model:checked 或者 v-model:fileList
     modelPropNameMap: {
       Checkbox: 'checked',
@@ -87,55 +92,32 @@ import type { BaseFormComponentType } from '@vben/common-ui';
 import type { Component, SetupContext } from 'vue';
 import { h } from 'vue';
 
-import { globalShareState, IconPicker } from '@vben/common-ui';
+import { globalShareState } from '@vben/common-ui';
 import { $t } from '@vben/locales';
-
-const AutoComplete = defineAsyncComponent(
-  () => import('ant-design-vue/es/auto-complete'),
-);
-const Button = defineAsyncComponent(() => import('ant-design-vue/es/button'));
-const Checkbox = defineAsyncComponent(
-  () => import('ant-design-vue/es/checkbox'),
-);
-const CheckboxGroup = defineAsyncComponent(() =>
-  import('ant-design-vue/es/checkbox').then((res) => res.CheckboxGroup),
-);
-const DatePicker = defineAsyncComponent(
-  () => import('ant-design-vue/es/date-picker'),
-);
-const Divider = defineAsyncComponent(() => import('ant-design-vue/es/divider'));
-const Input = defineAsyncComponent(() => import('ant-design-vue/es/input'));
-const InputNumber = defineAsyncComponent(
-  () => import('ant-design-vue/es/input-number'),
-);
-const InputPassword = defineAsyncComponent(() =>
-  import('ant-design-vue/es/input').then((res) => res.InputPassword),
-);
-const Mentions = defineAsyncComponent(
-  () => import('ant-design-vue/es/mentions'),
-);
-const Radio = defineAsyncComponent(() => import('ant-design-vue/es/radio'));
-const RadioGroup = defineAsyncComponent(() =>
-  import('ant-design-vue/es/radio').then((res) => res.RadioGroup),
-);
-const RangePicker = defineAsyncComponent(() =>
-  import('ant-design-vue/es/date-picker').then((res) => res.RangePicker),
-);
-const Rate = defineAsyncComponent(() => import('ant-design-vue/es/rate'));
-const Select = defineAsyncComponent(() => import('ant-design-vue/es/select'));
-const Space = defineAsyncComponent(() => import('ant-design-vue/es/space'));
-const Switch = defineAsyncComponent(() => import('ant-design-vue/es/switch'));
-const Textarea = defineAsyncComponent(() =>
-  import('ant-design-vue/es/input').then((res) => res.Textarea),
-);
-const TimePicker = defineAsyncComponent(
-  () => import('ant-design-vue/es/time-picker'),
-);
-const TreeSelect = defineAsyncComponent(
-  () => import('ant-design-vue/es/tree-select'),
-);
-const Upload = defineAsyncComponent(() => import('ant-design-vue/es/upload'));
-
+import {
+  AutoComplete,
+  Button,
+  Checkbox,
+  CheckboxGroup,
+  DatePicker,
+  Divider,
+  Input,
+  InputNumber,
+  InputPassword,
+  Mentions,
+  notification,
+  Radio,
+  RadioGroup,
+  RangePicker,
+  Rate,
+  Select,
+  Space,
+  Switch,
+  Textarea,
+  TimePicker,
+  TreeSelect,
+  Upload,
+} from 'ant-design-vue';
 
 const withDefaultPlaceholder = <T extends Component>(
   component: T,
@@ -171,7 +153,6 @@ export type ComponentType =
   | 'TimePicker'
   | 'TreeSelect'
   | 'Upload'
-  | 'IconPicker';
   | BaseFormComponentType;
 
 async function initComponentAdapter() {
@@ -189,7 +170,6 @@ async function initComponentAdapter() {
       return h(Button, { ...props, attrs, type: 'default' }, slots);
     },
     Divider,
-    IconPicker,
     Input: withDefaultPlaceholder(Input, 'input'),
     InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
     InputPassword: withDefaultPlaceholder(InputPassword, 'input'),

+ 1 - 1
docs/src/components/common-ui/vben-modal.md

@@ -69,7 +69,7 @@ Modal 内的内容一般业务中,会比较复杂,所以我们可以将 moda
 
 - `VbenModal` 组件对与参数的处理优先级是 `slot` > `props` > `state`(通过api更新的状态以及useVbenModal参数)。如果你已经传入了 `slot` 或者 `props`,那么 `setState` 将不会生效,这种情况下你可以通过 `slot` 或者 `props` 来更新状态。
 - 如果你使用到了 `connectedComponent` 参数,那么会存在 2 个`useVbenModal`, 此时,如果同时设置了相同的参数,那么以内部为准(也就是没有设置 connectedComponent 的代码)。比如 同时设置了 `onConfirm`,那么以内部的 `onConfirm` 为准。`onOpenChange`事件除外,内外都会触发。另外,如果设置了`destroyOnClose`,内部Modal及其子组件会在被关闭后<b>完全销毁</b>。
-- 如果弹窗的默认行为不符合你的预期,可以在`src\bootstrap.ts`中修改`setDefaultModalProps`的参数来设置默认的属性,如默认隐藏全屏按钮,修改默认ZIndex等。
+- 如果弹窗的默认行为不符合你的预期,可以在对应应用的 `apps/<app>/src/bootstrap.ts` 中修改 `setDefaultModalProps` 的参数来设置默认属性,例如默认隐藏全屏按钮、修改默认 `zIndex` 等。
 
 :::
 

+ 50 - 77
docs/src/components/common-ui/vben-vxe-table.md

@@ -4,25 +4,19 @@ outline: deep
 
 # Vben Vxe Table 表格
 
-框架提供的Table 列表组件基于 [vxe-table](https://vxetable.cn/v4/#/grid/api?apiKey=grid),结合`Vben Form 表单`进行了二次封装
+`Vben Vxe Table` 基于 [vxe-table](https://vxetable.cn/v4/#/grid/api?apiKey=grid) 和 `Vben Form` 做了二次封装,用于构建带搜索表单的列表页面
 
-其中,表头的 **表单搜索** 部分采用了`Vben Form表单`,表格主体部分使用了`vxe-grid`组件,支持表格的分页、排序、筛选等功能。
-
-> 如果文档内没有参数说明,可以尝试在在线示例或者在 [vxe-grid 官方API 文档](https://vxetable.cn/v4/#/grid/api?apiKey=grid) 内寻找
+> 如果文档内没有覆盖到你需要的细节,可以结合在线示例和 [vxe-grid 官方 API](https://vxetable.cn/v4/#/grid/api?apiKey=grid) 一起查看。
 
 ::: info 写在前面
 
-如果你觉得现有组件的封装不够理想,或者不完全符合你的需求,大可以直接使用原生组件,亦或亲手封装一个适合的组件。框架提供的组件并非束缚,使用与否,完全取决于你的需求与自由。
-
-:::
+如果现有封装不满足你的场景,可以直接使用原生 `vxe-table` 能力,或者在适配层中继续扩展。:::
 
 ## 适配器
 
-表格底层使用 [vxe-table](https://vxetable.cn/#/start/install) 进行实现,所以你可以使用 `vxe-table` 的所有功能。对于不同的 UI 框架,我们提供了适配器,以便更好的适配不同的 UI 框架
+底层表格基于 `vxe-table`,每个应用都可以在自己的适配层中配置默认行为、自定义渲染器以及与 UI 组件库的集成
 
-### 适配器说明
-
-每个应用都可以自己配置`vxe-table`的适配器,你可以根据自己的需求。下面是一个简单的配置示例:
+### 适配器示例
 
 ::: details vxe-table 表格适配器
 
@@ -46,7 +40,6 @@ setupVbenVxeTable({
         },
         minHeight: 180,
         formConfig: {
-          // 全局禁用vxe-table的表单配置,使用formOptions
           enabled: false,
         },
         proxyConfig: {
@@ -65,7 +58,6 @@ setupVbenVxeTable({
       },
     });
 
-    // 表格配置项可以用 cellRender: { name: 'CellImage' },
     vxeUI.renderer.add('CellImage', {
       renderTableDefault(_renderOpts, params) {
         const { column, row } = params;
@@ -73,7 +65,6 @@ setupVbenVxeTable({
       },
     });
 
-    // 表格配置项可以用 cellRender: { name: 'CellLink' },
     vxeUI.renderer.add('CellLink', {
       renderTableDefault(renderOpts) {
         const { props } = renderOpts;
@@ -84,9 +75,6 @@ setupVbenVxeTable({
         );
       },
     });
-
-    // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
-    // vxeUI.formats.add
   },
   useVbenForm,
 });
@@ -100,55 +88,50 @@ export type * from '@vben/plugins/vxe-table';
 
 ## 基础表格
 
-使用 `useVbenVxeGrid` 创建最基础的表格。
+通过 `useVbenVxeGrid` 创建一个基础表格。
 
 <DemoPreview dir="demos/vben-vxe-table/basic" />
 
 ## 远程加载
 
-通过指定 `proxyConfig.ajax` 的 `query` 方法,可以实现远程加载数据
+通过配置 `proxyConfig.ajax.query` 实现远程数据加载
 
 <DemoPreview dir="demos/vben-vxe-table/remote" />
 
 ## 树形表格
 
-树形表格的数据源为扁平结构,可以指定`treeConfig`配置项,实现树形表格
+树形表格的数据源通常是扁平结构,可以通过 `treeConfig` 转换为树形展示
 
-```typescript
+```ts
 treeConfig: {
-  transform: true, // 指定表格为树形表格
-  parentField: 'parentId', // 父节点字段名
-  rowField: 'id', // 行数据字段名
+  transform: true,
+  parentField: 'parentId',
+  rowField: 'id',
 },
 ```
 
 <DemoPreview dir="demos/vben-vxe-table/tree" />
 
-## 固定表头/
+## 固定列
 
-列固定可选参数: `'left' | 'right' | '' | null`
+固定列可选值为 `'left' | 'right' | '' | null`。
 
 <DemoPreview dir="demos/vben-vxe-table/fixed" />
 
 ## 自定义单元格
 
-自定义单元格有两种实现方式
+可以通过插槽或自定义渲染器实现单元格定制。
 
-- 通过 `slots` 插槽
-- 通过 `customCell` 自定义单元格,但是要先添加渲染器
-
-```typescript
-// 表格配置项可以用 cellRender: { name: 'CellImage' },
+```ts
 vxeUI.renderer.add('CellImage', {
-  renderDefault(_renderOpts, params) {
+  renderTableDefault(_renderOpts, params) {
     const { column, row } = params;
-    return h(Image, { src: row[column.field] } as any); // 注意此处的Image 组件,来源于Antd,需要自行引入,否则会使用js的Image类
+    return h(Image, { src: row[column.field] } as any);
   },
 });
 
-// 表格配置项可以用 cellRender: { name: 'CellLink' },
 vxeUI.renderer.add('CellLink', {
-  renderDefault(renderOpts) {
+  renderTableDefault(renderOpts) {
     const { props } = renderOpts;
     return h(
       Button,
@@ -163,23 +146,20 @@ vxeUI.renderer.add('CellLink', {
 
 ## 搜索表单
 
-**表单搜索** 部分采用了`Vben Form 表单`,参考 [Vben Form 表单文档](/components/common-ui/vben-form)
+搜索区域底层使用的是 `Vben Form`。启用搜索表单后,可以通过 `gridOptions.toolbarConfig.search = true` 在工具栏中显示搜索面板开关按钮
 
-当启用了表单搜索时,可以在toolbarConfig中配置`search`为`true`来让表格在工具栏区域显示一个搜索表单控制按钮。表格的所有以`form-`开头的命名插槽都会被传递给搜索表单。
+所有以 `form-` 开头的具名插槽都会自动转发到搜索表单。
 
-### 定制分隔条
+### 自定义分隔条
 
-当你启用表单搜索时,在表单和表格之间会显示一个分隔条。这个分隔条使用了默认的组件背景色,并且横向贯穿整个Vben Vxe Table在视觉上融入了页面的默认背景中。如果你在Vben Vxe Table的外层包裹了一个不同背景色的容器(如将其放在一个Card内),默认的表单和表格之间的分隔条可能就显得格格不入了,下面的代码演示了如何定制这个分隔条
+启用搜索表单时,表单和表格主体之间默认会显示一个分隔条。可以通过 `separator` 调整或关闭它
 
 ```ts
 const [Grid] = useVbenVxeGrid({
   formOptions: {},
   gridOptions: {},
-  // 完全移除分隔条
   separator: false,
-  // 你也可以使用下面的代码来移除分隔条
   // separator: { show: false },
-  // 或者使用下面的代码来改变分隔条的颜色
   // separator: { backgroundColor: 'rgba(100,100,0,0.5)' },
 });
 ```
@@ -188,40 +168,36 @@ const [Grid] = useVbenVxeGrid({
 
 ## 单元格编辑
 
-通过指定`editConfig.mode`为`cell`,可以实现单元格编辑。
+通过设置 `editConfig.mode = 'cell'` 开启单元格编辑。
 
 <DemoPreview dir="demos/vben-vxe-table/edit-cell" />
 
 ## 行编辑
 
-通过指定`editConfig.mode`为`row`,可以实现行编辑。
+通过设置 `editConfig.mode = 'row'` 开启整行编辑。
 
 <DemoPreview dir="demos/vben-vxe-table/edit-row" />
 
 ## 虚拟滚动
 
-通过 scroll-y.enabled 与 scroll-y.gt 组合开启,其中 enabled 为总开关,gt 是指当总行数大于指定行数时自动开启
+通过 `scroll-y.enabled` 和 `scroll-y.gt` 组合开启纵向虚拟滚动
 
-> 参考 [vxe-table 官方文档 - 虚拟滚动](https://vxetable.cn/v4/#/component/grid/scroll/vertical)
+> 参考 [vxe-table 官方文档 - 虚拟滚动](https://vxetable.cn/v4/#/component/grid/scroll/vertical)
 
 <DemoPreview dir="demos/vben-vxe-table/virtual" />
 
 ## API
 
-`useVbenVxeGrid` 返回一个数组,第一个元素是表格组件,第二个元素是表格的方法
+`useVbenVxeGrid` 返回一个数组,第一个元素是表格组件,第二个元素是表格 API
 
 ```vue
 <script setup lang="ts">
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
 
-// Grid 为表格组件
-// gridApi 为表格的方法
 const [Grid, gridApi] = useVbenVxeGrid({
   gridOptions: {},
   formOptions: {},
   gridEvents: {},
-  // 属性
-  // 事件
 });
 </script>
 
@@ -232,45 +208,42 @@ const [Grid, gridApi] = useVbenVxeGrid({
 
 ### GridApi
 
-useVbenVxeGrid 返回的第二个参数,是一个对象,包含了一些表单的方法。
-
 | 方法名 | 描述 | 类型 | 说明 |
 | --- | --- | --- | --- |
-| setLoading | 设置loading状态 | `(loading)=>void` | - |
-| setGridOptions | 设置vxe-table grid组件参数 | `(options: Partial<VxeGridProps['gridOptions'])=>void` | - |
-| reload | 重载表格,会进行初始化 | `(params:any)=>void` | - |
-| query | 重载表格,会保留当前分页 | `(params:any)=>void` | - |
-| grid | vxe-table grid实例 | `VxeGridInstance` | - |
-| formApi | vbenForm api实例 | `FormApi` | - |
-| toggleSearchForm | 设置搜索表单显示状态 | `(show?: boolean)=>boolean` | 当省略参数时,则将表单在显示和隐藏两种状态之间切换 |
+| setLoading | 设置 loading 状态 | `(loading: boolean) => void` | - |
+| setGridOptions | 更新 `gridOptions` | `(options: Partial<VxeGridProps['gridOptions']>) => void` | - |
+| reload | 重新加载表格,并重置到初始分页 | `(params?: Record<string, any>) => void` | - |
+| query | 重新查询表格,保留当前分页 | `(params?: Record<string, any>) => void` | - |
+| grid | `vxe-grid` 实例 | `VxeGridInstance` | - |
+| formApi | 搜索表单 API 实例 | `FormApi` | - |
+| toggleSearchForm | 切换或指定搜索表单显示状态 | `(show?: boolean) => boolean` | 传入参数时强制设置;不传参数时在显示和隐藏之间切换,并返回当前状态 |
 
 ## Props
 
-所有属性都可以传入 `useVbenVxeGrid` 的第一个参数中
+所有属性都通过 `useVbenVxeGrid` 的第一个参数传入
 
 | 属性名 | 描述 | 类型 | 版本要求 |
 | --- | --- | --- | --- |
 | tableTitle | 表格标题 | `string` | - |
 | tableTitleHelp | 表格标题帮助信息 | `string` | - |
-| gridClass | grid组件的class | `string` | - |
-| gridOptions | grid组件的参数 | `VxeTableGridProps` | - |
-| gridEvents | grid组件的触发的事件 | `VxeGridListeners` | - |
-| formOptions | 表单参数 | `VbenFormProps` | - |
+| class | 外层容器的 class | `string` | - |
+| gridClass | `vxe-grid` 的 class | `string` | - |
+| gridOptions | `vxe-grid` 配置 | `DeepPartial<VxeTableGridOptions>` | - |
+| gridEvents | `vxe-grid` 事件 | `DeepPartial<VxeGridListeners>` | - |
+| formOptions | 搜索表单配置 | `VbenFormProps` | - |
 | showSearchForm | 是否显示搜索表单 | `boolean` | - |
-| separator | 搜索表单与表格主体之间的分隔条 | `boolean\|SeparatorOptions` | >5.5.4 |
+| separator | 搜索表单与表格主体之间的分隔条 | `boolean \| SeparatorOptions` | `>5.5.4` |
 
 ## Slots
 
-大部分插槽的说明请参考 [vxe-table 官方文档](https://vxetable.cn/v4/#/grid/api),但工具栏部分由于做了一些定制封装,需使用以下插槽定制表格的工具栏:
+大部分插槽说明可参考 [vxe-table 官方文档](https://vxetable.cn/v4/#/grid/api),这里列出封装层新增或约定的部分。
 
-| 插槽名          | 描述                                         |
-| --------------- | -------------------------------------------- |
-| toolbar-actions | 工具栏左侧部分(表格标题附近)               |
-| toolbar-tools   | 工具栏右侧部分(vxeTable原生工具按钮的左侧) |
-| table-title     | 表格标题插槽                                 |
+| 插槽名          | 描述                                 |
+| --------------- | ------------------------------------ |
+| toolbar-actions | 工具栏左侧区域,位于标题附近         |
+| toolbar-tools   | 工具栏右侧区域,位于内置工具按钮左侧 |
+| table-title     | 自定义表格标题                       |
 
-::: info 搜索表单插槽
+::: info 搜索表单插槽
 
-对于使用了搜索表单的表格来说,所有以`form-`开头的命名插槽都会传递给表单。
-
-:::
+当启用了搜索表单时,所有以 `form-` 开头的具名插槽都会被转发给表单。:::

+ 18 - 21
docs/src/components/layout-ui/page.md

@@ -4,41 +4,38 @@ outline: deep
 
 # Page 常规页面组件
 
-提供一个常规页面布局的组件,包括头部、内容区域、底部三个部分
+`Page` 是页面内容区最常用的顶层布局容器,内置了标题区、内容区和底部区三部分结构
 
 ::: info 写在前面
 
-本组件是一个基本布局组件。如果有更多的通用页面布局需求(比如双列布局等),可以根据实际需求自行封装。
-
-:::
+这是一个基础页面容器。如果你的业务页面需要更复杂的布局,例如双列、侧边操作区或自定义滚动区域,建议在 `Page` 之上继续封装。:::
 
 ## 基础用法
 
-将`Page`作为你的业务页面的根组件即可。
+直接 `Page` 作为业务页面的根组件使用即可。
 
 ### Props
 
 | 属性名 | 描述 | 类型 | 默认值 | 说明 |
 | --- | --- | --- | --- | --- |
-| title | 页面标题 | `string\|slot` | - | - |
-| description | 页面描述(标题下的内容) | `string\|slot` | - | - |
-| contentClass | 内容区域的class | `string` | - | - |
-| headerClass | 头部区域的class | `string` | - | - |
-| footerClass | 底部区域的class | `string` | - | - |
-| autoContentHeight | 自动调整内容区域的高度 | `boolean` | `false` | - |
+| title | 页面标题 | `string \| slot` | - | - |
+| description | 页面描述 | `string \| slot` | - | - |
+| contentClass | 内容区域的 class | `string` | - | - |
+| headerClass | 头部区域的 class | `string` | - | - |
+| footerClass | 底部区域的 class | `string` | - | - |
+| autoContentHeight | 根据可视内容高度自动计算内容区高度 | `boolean` | `false` | 开启后内容区会根据布局可视高度自动扣减头部和底部高度 |
+| heightOffset | 额外扣减的内容区高度偏移量 | `number` | `0` | 仅在 `autoContentHeight` 开启时生效,单位为 `px` |
 
 ::: tip 注意
 
-如果`title`、`description`、`extra`三者均未提供有效内容(通过`props`或者`slots`均可),则页面头部区域不会渲染。
-
-:::
+如果 `title`、`description`、`extra` 三者都没有提供有效内容,无论是通过 `props` 还是 `slots`,头部区域都不会渲染。:::
 
 ### Slots
 
-| 插槽名称    | 描述         |
-| ----------- | ------------ |
-| default     | 页面内容     |
-| title       | 页面标题     |
-| description | 页面描述     |
-| extra       | 页面头部右侧 |
-| footer      | 页面底部     |
+| 插槽名称    | 描述             |
+| ----------- | ---------------- |
+| default     | 页面内容         |
+| title       | 页面标题         |
+| description | 页面描述         |
+| extra       | 页面头部右侧内容 |
+| footer      | 页面底部内容     |

+ 76 - 0
docs/src/en/components/common-ui/vben-alert.md

@@ -0,0 +1,76 @@
+---
+outline: deep
+---
+
+# Vben Alert
+
+`Alert` provides lightweight JavaScript-driven dialogs for simple `alert`, `confirm`, and `prompt` style interactions.
+
+## Basic Usage
+
+Use `alert` for a single confirm button dialog:
+
+<DemoPreview dir="demos/vben-alert/alert" />
+
+Use `confirm` for confirm/cancel interactions:
+
+<DemoPreview dir="demos/vben-alert/confirm" />
+
+Use `prompt` when you need simple user input:
+
+<DemoPreview dir="demos/vben-alert/prompt" />
+
+## useAlertContext
+
+If `content`, `footer`, or `icon` is rendered through a custom component, you can call `useAlertContext()` inside that component to access the current dialog actions.
+
+| Method      | Description                | Type         |
+| ----------- | -------------------------- | ------------ |
+| `doConfirm` | trigger the confirm action | `() => void` |
+| `doCancel`  | trigger the cancel action  | `() => void` |
+
+## Core Types
+
+```ts
+export type IconType = 'error' | 'info' | 'question' | 'success' | 'warning';
+
+export type BeforeCloseScope = {
+  isConfirm: boolean;
+};
+
+export type AlertProps = {
+  beforeClose?: (
+    scope: BeforeCloseScope,
+  ) => boolean | Promise<boolean | undefined> | undefined;
+  bordered?: boolean;
+  buttonAlign?: 'center' | 'end' | 'start';
+  cancelText?: string;
+  centered?: boolean;
+  confirmText?: string;
+  containerClass?: string;
+  content: Component | string;
+  contentClass?: string;
+  contentMasking?: boolean;
+  footer?: Component | string;
+  icon?: Component | IconType;
+  overlayBlur?: number;
+  showCancel?: boolean;
+  title?: string;
+};
+
+export type PromptProps<T = any> = {
+  beforeClose?: (scope: {
+    isConfirm: boolean;
+    value: T | undefined;
+  }) => boolean | Promise<boolean | undefined> | undefined;
+  component?: Component;
+  componentProps?: Recordable<any>;
+  componentSlots?:
+    | (() => any)
+    | Recordable<unknown>
+    | VNode
+    | VNodeArrayChildren;
+  defaultValue?: T;
+  modelPropName?: string;
+} & Omit<AlertProps, 'beforeClose'>;
+```

+ 69 - 0
docs/src/en/components/common-ui/vben-api-component.md

@@ -0,0 +1,69 @@
+---
+outline: deep
+---
+
+# Vben ApiComponent
+
+`ApiComponent` is a wrapper used to attach remote-option loading behavior to an existing component while preserving the original component usage pattern.
+
+## Common Usage
+
+The current wrapper flow is:
+
+- pass the target component through `component`
+- fetch remote data through `api`
+- transform data through `beforeFetch` and `afterFetch`
+- map remote fields through `resultField`, `valueField`, `labelField`, and `childrenField`
+- pass normalized options to the target component through `optionsPropName`
+
+```vue
+<script lang="ts" setup>
+import { ApiComponent } from '@vben/common-ui';
+
+import { Cascader } from 'ant-design-vue';
+
+function fetchApi() {
+  return Promise.resolve([
+    {
+      label: 'Zhejiang',
+      value: 'zhejiang',
+      children: [{ label: 'Hangzhou', value: 'hangzhou' }],
+    },
+  ]);
+}
+</script>
+
+<template>
+  <ApiComponent
+    :api="fetchApi"
+    :component="Cascader"
+    :immediate="false"
+    children-field="children"
+    loading-slot="suffixIcon"
+    visible-event="onDropdownVisibleChange"
+  />
+</template>
+```
+
+## Current Props
+
+| Prop | Description | Type |
+| --- | --- | --- |
+| `component` | wrapped target component | `Component` |
+| `api` | remote request function | `(arg?: any) => Promise<any>` |
+| `params` | extra request params | `Record<string, any>` |
+| `beforeFetch` | hook before request | `AnyPromiseFunction` |
+| `afterFetch` | hook after request | `AnyPromiseFunction` |
+| `visibleEvent` | event name used to lazy-load data | `string` |
+| `loadingSlot` | slot name used to render the loading icon | `string` |
+| `modelPropName` | model prop name of the wrapped component | `string` |
+| `autoSelect` | auto-pick the first / last / only option, or use a custom function | `'first' \| 'last' \| 'one' \| ((items) => item) \| false` |
+
+## Exposed Methods
+
+| Method                   | Description                            |
+| ------------------------ | -------------------------------------- |
+| `getComponentRef()`      | returns the wrapped component instance |
+| `updateParam(newParams)` | merges and updates request params      |
+| `getOptions()`           | returns loaded options                 |
+| `getValue()`             | returns the current bound value        |

+ 51 - 0
docs/src/en/components/common-ui/vben-count-to-animator.md

@@ -0,0 +1,51 @@
+---
+outline: deep
+---
+
+# Vben CountToAnimator
+
+`CountToAnimator` renders animated number transitions.
+
+## Basic Usage
+
+Use `start-val`, `end-val`, and `duration` to control the animation range and timing.
+
+<DemoPreview dir="demos/vben-count-to-animator/basic" />
+
+## Formatting
+
+Use `prefix`, `suffix`, `separator`, and `decimal` to control how the number is displayed.
+
+<DemoPreview dir="demos/vben-count-to-animator/custom" />
+
+## Props
+
+| Prop | Description | Type | Default |
+| --- | --- | --- | --- |
+| `startVal` | starting value | `number` | `0` |
+| `endVal` | ending value | `number` | `2021` |
+| `duration` | animation duration in ms | `number` | `1500` |
+| `autoplay` | start automatically | `boolean` | `true` |
+| `prefix` | value prefix | `string` | `''` |
+| `suffix` | value suffix | `string` | `''` |
+| `separator` | thousands separator | `string` | `','` |
+| `decimal` | decimal separator | `string` | `'.'` |
+| `color` | text color | `string` | `''` |
+| `useEasing` | enable transition preset easing | `boolean` | `true` |
+| `transition` | transition preset name | `keyof typeof TransitionPresets` | `'linear'` |
+| `decimals` | decimal places to keep | `number` | `0` |
+
+## Events
+
+| Event        | Description                     | Type         |
+| ------------ | ------------------------------- | ------------ |
+| `started`    | fired when the animation starts | `() => void` |
+| `finished`   | fired when the animation ends   | `() => void` |
+| `onStarted`  | deprecated alias of `started`   | `() => void` |
+| `onFinished` | deprecated alias of `finished`  | `() => void` |
+
+## Exposed Methods
+
+| Method  | Description                       | Type         |
+| ------- | --------------------------------- | ------------ |
+| `reset` | reset to `startVal` and run again | `() => void` |

+ 56 - 0
docs/src/en/components/common-ui/vben-drawer.md

@@ -0,0 +1,56 @@
+---
+outline: deep
+---
+
+# Vben Drawer
+
+`Vben Drawer` is the shared drawer wrapper used by the framework. It supports auto-height layout, loading state, connected components, and an imperative API similar to the modal API.
+
+## Basic Usage
+
+```ts
+const [Drawer, drawerApi] = useVbenDrawer({
+  // props
+  // events
+});
+```
+
+<DemoPreview dir="demos/vben-drawer/basic" />
+
+## Current Usage Notes
+
+- If you use `connectedComponent`, the inner and outer components share data through `drawerApi.setData()` and `drawerApi.getData()`.
+- Default drawer behavior can be adjusted in `apps/<app>/src/bootstrap.ts` through `setDefaultDrawerProps(...)`.
+- `setState(...)` works on `DrawerState`, not `ModalState`.
+
+## Key Props
+
+| Prop | Description | Type |
+| --- | --- | --- |
+| `appendToMain` | mount inside the main content area instead of `body` | `boolean` |
+| `connectedComponent` | connect an inner component to the drawer wrapper | `Component` |
+| `closeIconPlacement` | position of the close icon | `'left' \| 'right'` |
+| `placement` | drawer side | `'left' \| 'right' \| 'top' \| 'bottom'` |
+| `overlayBlur` | blur amount for the overlay | `number` |
+| `submitting` | lock drawer interactions while submitting | `boolean` |
+
+## Events
+
+| Event | Description | Type |
+| --- | --- | --- |
+| `onBeforeClose` | called before close; returning `false` or rejecting prevents close | `() => Promise<boolean \| undefined> \| boolean \| undefined` |
+| `onOpenChange` | called when open state changes | `(isOpen: boolean) => void` |
+| `onOpened` | called after open animation completes | `() => void` |
+| `onClosed` | called after close animation completes | `() => void` |
+
+## drawerApi
+
+| Method                  | Description                            |
+| ----------------------- | -------------------------------------- |
+| `setState(...)`         | updates drawer state                   |
+| `open()`                | opens the drawer                       |
+| `close()`               | closes the drawer                      |
+| `setData(data)`         | stores shared data                     |
+| `getData<T>()`          | reads shared data                      |
+| `lock(isLocked = true)` | locks the drawer into submitting state |
+| `unlock()`              | alias for `lock(false)`                |

+ 42 - 0
docs/src/en/components/common-ui/vben-ellipsis-text.md

@@ -0,0 +1,42 @@
+---
+outline: deep
+---
+
+# Vben EllipsisText
+
+`EllipsisText` displays long text with truncation, tooltip support, and optional expand/collapse behavior.
+
+## Basic Usage
+
+Pass the text through the default slot and limit the visual width with `maxWidth`.
+
+<DemoPreview dir="demos/vben-ellipsis-text/line" />
+
+## Current Props
+
+| Prop | Description | Type | Default |
+| --- | --- | --- | --- |
+| `expand` | allow click-to-expand behavior | `boolean` | `false` |
+| `line` | max visible line count | `number` | `1` |
+| `maxWidth` | max width of the text area | `number \| string` | `'100%'` |
+| `placement` | tooltip placement | `'bottom' \| 'left' \| 'right' \| 'top'` | `'top'` |
+| `tooltip` | enable tooltip | `boolean` | `true` |
+| `tooltipWhenEllipsis` | only show tooltip when text is actually truncated | `boolean` | `false` |
+| `ellipsisThreshold` | pixel threshold used when checking truncation | `number` | `3` |
+| `tooltipBackgroundColor` | tooltip background color | `string` | `''` |
+| `tooltipColor` | tooltip text color | `string` | `''` |
+| `tooltipFontSize` | tooltip font size in px | `number` | `14` |
+| `tooltipMaxWidth` | tooltip max width in px | `number` | - |
+| `tooltipOverlayStyle` | tooltip content style | `CSSProperties` | `{ textAlign: 'justify' }` |
+
+## Events
+
+| Event | Description | Type |
+| --- | --- | --- |
+| `expandChange` | fired when expand state changes | `(isExpand: boolean) => void` |
+
+## Slots
+
+| Slot      | Description            |
+| --------- | ---------------------- |
+| `tooltip` | custom tooltip content |

+ 203 - 0
docs/src/en/components/common-ui/vben-form.md

@@ -0,0 +1,203 @@
+---
+outline: deep
+---
+
+# Vben Form
+
+`Vben Form` is the shared form abstraction used across different UI-library variants such as `Ant Design Vue`, `Element Plus`, `Naive UI`, and other adapters added inside this repository.
+
+> If some details are not obvious from the docs, check the live demos as well.
+
+## Adapter Setup
+
+Each app keeps its own adapter layer under `src/adapter/form.ts` and `src/adapter/component/index.ts`.
+
+The current adapter pattern is:
+
+- initialize the shared component adapter first
+- call `setupVbenForm(...)`
+- map special `v-model:*` prop names through `modelPropNameMap`
+- keep the form empty state aligned with the actual UI library behavior
+
+### Form Adapter Example
+
+```ts
+import type {
+  VbenFormSchema as FormSchema,
+  VbenFormProps,
+} from '@vben/common-ui';
+
+import type { ComponentType } from './component';
+
+import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
+import { $t } from '@vben/locales';
+
+import { initComponentAdapter } from './component';
+
+initComponentAdapter();
+setupVbenForm<ComponentType>({
+  config: {
+    baseModelPropName: 'value',
+    emptyStateValue: null,
+    modelPropNameMap: {
+      Checkbox: 'checked',
+      Radio: 'checked',
+      Switch: 'checked',
+      Upload: 'fileList',
+    },
+  },
+  defineRules: {
+    required: (value, _params, ctx) => {
+      if (value === undefined || value === null || value.length === 0) {
+        return $t('ui.formRules.required', [ctx.label]);
+      }
+      return true;
+    },
+    selectRequired: (value, _params, ctx) => {
+      if (value === undefined || value === null) {
+        return $t('ui.formRules.selectRequired', [ctx.label]);
+      }
+      return true;
+    },
+  },
+});
+
+const useVbenForm = useForm<ComponentType>;
+
+export { useVbenForm, z };
+export type VbenFormSchema = FormSchema<ComponentType>;
+export type { VbenFormProps };
+```
+
+### Component Adapter Example
+
+```ts
+import type { Component, SetupContext } from 'vue';
+
+import type { BaseFormComponentType } from '@vben/common-ui';
+
+import { h } from 'vue';
+
+import { globalShareState } from '@vben/common-ui';
+import { $t } from '@vben/locales';
+import {
+  AutoComplete,
+  Button,
+  Checkbox,
+  CheckboxGroup,
+  DatePicker,
+  Divider,
+  Input,
+  InputNumber,
+  InputPassword,
+  Mentions,
+  notification,
+  Radio,
+  RadioGroup,
+  RangePicker,
+  Rate,
+  Select,
+  Space,
+  Switch,
+  Textarea,
+  TimePicker,
+  TreeSelect,
+  Upload,
+} from 'ant-design-vue';
+
+const withDefaultPlaceholder = <T extends Component>(
+  component: T,
+  type: 'input' | 'select',
+) => {
+  return (props: any, { attrs, slots }: Omit<SetupContext, 'expose'>) => {
+    const placeholder = props?.placeholder || $t(`ui.placeholder.${type}`);
+    return h(component, { ...props, ...attrs, placeholder }, slots);
+  };
+};
+
+export type ComponentType =
+  | 'AutoComplete'
+  | 'Checkbox'
+  | 'CheckboxGroup'
+  | 'DatePicker'
+  | 'DefaultButton'
+  | 'Divider'
+  | 'Input'
+  | 'InputNumber'
+  | 'InputPassword'
+  | 'Mentions'
+  | 'PrimaryButton'
+  | 'Radio'
+  | 'RadioGroup'
+  | 'RangePicker'
+  | 'Rate'
+  | 'Select'
+  | 'Space'
+  | 'Switch'
+  | 'Textarea'
+  | 'TimePicker'
+  | 'TreeSelect'
+  | 'Upload'
+  | BaseFormComponentType;
+
+async function initComponentAdapter() {
+  const components: Partial<Record<ComponentType, Component>> = {
+    AutoComplete,
+    Checkbox,
+    CheckboxGroup,
+    DatePicker,
+    DefaultButton: (props, { attrs, slots }) => {
+      return h(Button, { ...props, attrs, type: 'default' }, slots);
+    },
+    Divider,
+    Input: withDefaultPlaceholder(Input, 'input'),
+    InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
+    InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
+    Mentions: withDefaultPlaceholder(Mentions, 'input'),
+    PrimaryButton: (props, { attrs, slots }) => {
+      return h(Button, { ...props, attrs, type: 'primary' }, slots);
+    },
+    Radio,
+    RadioGroup,
+    RangePicker,
+    Rate,
+    Select: withDefaultPlaceholder(Select, 'select'),
+    Space,
+    Switch,
+    Textarea: withDefaultPlaceholder(Textarea, 'input'),
+    TimePicker,
+    TreeSelect: withDefaultPlaceholder(TreeSelect, 'select'),
+    Upload,
+  };
+
+  globalShareState.setComponents(components);
+  globalShareState.defineMessage({
+    copyPreferencesSuccess: (title, content) => {
+      notification.success({
+        description: content,
+        message: title,
+        placement: 'bottomRight',
+      });
+    },
+  });
+}
+
+export { initComponentAdapter };
+```
+
+## Basic Usage
+
+Create the form through `useVbenForm`:
+
+<DemoPreview dir="demos/vben-form/basic" />
+
+## Key API Notes
+
+- `useVbenForm` returns `[Form, formApi]`
+- `formApi.getFieldComponentRef()` and `formApi.getFocusedField()` are available in current versions
+- `handleValuesChange(values, fieldsChanged)` includes the second parameter in newer versions
+- `fieldMappingTime` and `scrollToFirstError` are part of the current form props
+
+## Reference
+
+For the complete Chinese API tables and more examples, see the Chinese component page if you need the full parameter matrix.

+ 56 - 0
docs/src/en/components/common-ui/vben-modal.md

@@ -0,0 +1,56 @@
+---
+outline: deep
+---
+
+# Vben Modal
+
+`Vben Modal` is the shared modal wrapper used by the framework. It supports draggable behavior, fullscreen mode, auto-height handling, loading state, connected components, and an imperative API.
+
+## Basic Usage
+
+```ts
+const [Modal, modalApi] = useVbenModal({
+  // props
+  // events
+});
+```
+
+<DemoPreview dir="demos/vben-modal/basic" />
+
+## Current Usage Notes
+
+- If you use `connectedComponent`, the inner and outer components share data through `modalApi.setData()` and `modalApi.getData()`.
+- When `connectedComponent` is present, avoid pushing extra modal props through the connected side. Prefer `useVbenModal(...)` or `modalApi.setState(...)`.
+- Default modal behavior can be adjusted in `apps/<app>/src/bootstrap.ts` through `setDefaultModalProps(...)`.
+
+## Key Props
+
+| Prop | Description | Type |
+| --- | --- | --- |
+| `appendToMain` | mount inside the main content area instead of `body` | `boolean` |
+| `connectedComponent` | connect an inner component to the modal wrapper | `Component` |
+| `animationType` | modal enter/leave animation | `'slide' \| 'scale'` |
+| `fullscreenButton` | show or hide the fullscreen toggle | `boolean` |
+| `overlayBlur` | blur amount for the overlay | `number` |
+| `submitting` | lock modal interactions while submitting | `boolean` |
+
+## Events
+
+| Event | Description | Type |
+| --- | --- | --- |
+| `onBeforeClose` | called before close; returning `false` or rejecting prevents close | `() => Promise<boolean \| undefined> \| boolean \| undefined` |
+| `onOpenChange` | called when open state changes | `(isOpen: boolean) => void` |
+| `onOpened` | called after open animation completes | `() => void` |
+| `onClosed` | called after close animation completes | `() => void` |
+
+## modalApi
+
+| Method                  | Description                           |
+| ----------------------- | ------------------------------------- |
+| `setState(...)`         | updates modal state                   |
+| `open()`                | opens the modal                       |
+| `close()`               | closes the modal                      |
+| `setData(data)`         | stores shared data                    |
+| `getData<T>()`          | reads shared data                     |
+| `lock(isLocked = true)` | locks the modal into submitting state |
+| `unlock()`              | alias for `lock(false)`               |

+ 87 - 0
docs/src/en/components/common-ui/vben-vxe-table.md

@@ -0,0 +1,87 @@
+---
+outline: deep
+---
+
+# Vben Vxe Table
+
+`Vben Vxe Table` wraps `vxe-table` together with `Vben Form` so you can build searchable data grids with a shared API.
+
+## Adapter Example
+
+The current renderer adapter uses `renderTableDefault(...)` for table cell rendering:
+
+```ts
+vxeUI.renderer.add('CellImage', {
+  renderTableDefault(_renderOpts, params) {
+    const { column, row } = params;
+    return h(Image, { src: row[column.field] });
+  },
+});
+
+vxeUI.renderer.add('CellLink', {
+  renderTableDefault(renderOpts) {
+    const { props } = renderOpts;
+    return h(
+      Button,
+      { size: 'small', type: 'link' },
+      { default: () => props?.text },
+    );
+  },
+});
+```
+
+## Basic Usage
+
+```vue
+<script setup lang="ts">
+import { useVbenVxeGrid } from '#/adapter/vxe-table';
+
+const [Grid, gridApi] = useVbenVxeGrid({
+  gridOptions: {},
+  formOptions: {},
+  gridEvents: {},
+});
+</script>
+
+<template>
+  <Grid />
+</template>
+```
+
+<DemoPreview dir="demos/vben-vxe-table/basic" />
+
+## GridApi
+
+| Method | Description | Type |
+| --- | --- | --- |
+| `setLoading` | update loading state | `(loading: boolean) => void` |
+| `setGridOptions` | merge new grid options | `(options: Partial<VxeGridProps['gridOptions']>) => void` |
+| `reload` | reload data and reset pagination | `(params?: Record<string, any>) => void` |
+| `query` | query data while keeping the current page | `(params?: Record<string, any>) => void` |
+| `grid` | `vxe-grid` instance | `VxeGridInstance` |
+| `formApi` | search form API | `FormApi` |
+| `toggleSearchForm` | toggle or force the search form visible state | `(show?: boolean) => boolean` |
+
+## Props
+
+| Prop | Description | Type |
+| --- | --- | --- |
+| `tableTitle` | table title | `string` |
+| `tableTitleHelp` | help text for the table title | `string` |
+| `class` | class for the outer container | `string` |
+| `gridClass` | class for the `vxe-grid` node | `string` |
+| `gridOptions` | `vxe-grid` options | `DeepPartial<VxeTableGridOptions>` |
+| `gridEvents` | `vxe-grid` event handlers | `DeepPartial<VxeGridListeners>` |
+| `formOptions` | search form options | `VbenFormProps` |
+| `showSearchForm` | whether the search form is visible | `boolean` |
+| `separator` | separator between the search form and table body | `boolean \| SeparatorOptions` |
+
+## Slots
+
+| Slot              | Description                                             |
+| ----------------- | ------------------------------------------------------- |
+| `toolbar-actions` | left side of the toolbar, near the title                |
+| `toolbar-tools`   | right side of the toolbar, before built-in tool buttons |
+| `table-title`     | custom table title                                      |
+
+All named slots starting with `form-` are forwarded to the search form.

+ 15 - 0
docs/src/en/components/introduction.md

@@ -0,0 +1,15 @@
+# Introduction
+
+::: info README
+
+This section documents the framework components, including their usage patterns, configuration points, and major APIs. If the built-in wrappers do not fit your needs, you can always use native components directly or build your own abstractions.
+
+:::
+
+## Layout Components
+
+Layout components are usually used as top-level containers inside the page content area. They provide shared layout styles and some baseline behavior.
+
+## Common Components
+
+Common components include frequently used UI building blocks such as modals, drawers, forms, and API-backed selectors. Most of them are implemented on top of shared Tailwind CSS and shadcn-vue based primitives, while still allowing each app to adapt them to its own UI library.

+ 29 - 0
docs/src/en/components/layout-ui/page.md

@@ -0,0 +1,29 @@
+---
+outline: deep
+---
+
+# Page
+
+`Page` is the standard top-level layout container for business pages. It provides a header area, a content area, and an optional footer area.
+
+## Props
+
+| Prop | Description | Type | Default |
+| --- | --- | --- | --- |
+| `title` | page title | `string \| slot` | - |
+| `description` | page description | `string \| slot` | - |
+| `contentClass` | class for the content area | `string` | - |
+| `headerClass` | class for the header area | `string` | - |
+| `footerClass` | class for the footer area | `string` | - |
+| `autoContentHeight` | auto-calculate the content area height from the visible layout height | `boolean` | `false` |
+| `heightOffset` | extra height offset subtracted from the content area when auto height is enabled | `number` | `0` |
+
+## Slots
+
+| Slot          | Description               |
+| ------------- | ------------------------- |
+| `default`     | page content              |
+| `title`       | custom title              |
+| `description` | custom description        |
+| `extra`       | right-side header content |
+| `footer`      | footer content            |