UNPKG

@vue-ui-kit/ant

Version:

Vue3 UI Kit based on Ant Design

540 lines (503 loc) 16.5 kB
import { TableColumnType, TableProps, TooltipProps } from 'ant-design-vue'; import { ButtonProps } from 'ant-design-vue/lib/button'; import type { Rule } from 'ant-design-vue/lib/form'; import { FormProps } from 'ant-design-vue/lib/form/Form'; import { ColProps } from 'ant-design-vue/lib/grid/Col'; import type { BorderConfigValue, ConfigType, Column as EVirtColumn } from 'e-virt-table'; import EVirtTable from 'e-virt-table'; export type { BorderConfigValue, BorderStyle } from 'e-virt-table'; /** 与 e-virt-table `scrollbarMode` 对齐:`outer` 外部预留,`inner` 内部悬停显示 */ export type ScrollbarMode = 'outer' | 'inner'; export interface CellFuncArg<D extends Recordable = Recordable> { row: D; column?: ColumnProps<D>; rowIndex: number; cellValue: any; } export type FormatterFunc = (c: CellFuncArg, ...args: any[]) => any; export type PFormatter = Record<string, FormatterFunc>; export interface ItemFuncArg<F extends Recordable = Recordable> { data: F; field?: string; } export interface ItemRender { name: string; defaultValue?: any; props?: Recordable; attrs?: Recordable; options?: IOption[]; children?: Recordable[]; events?: { [key: string]: (...args: any[]) => any }; } export interface CellRender { name: string; props?: Recordable; attrs?: Recordable; children?: Recordable[]; } export interface Responsive { xxs?: number; xs?: number; sm?: number; md?: number; lg?: number; xl?: number; xxl?: number; } export interface TooltipConfig extends TooltipProps { title: TooltipProps['title'] | (() => any); } export interface PFormItemProps<F extends Recordable = Recordable> { field?: string; title?: string; span?: number; colon?: boolean; labelCol?: ColProps; wrapperCol?: ColProps; forceRequired?: boolean; // 在页面需要必填标示,但field不需要必填校验时使用 align?: 'left' | 'right' | 'center'; col?: ColProps; rule?: Rule[]; itemRender?: ItemRender; tooltipConfig?: TooltipConfig; slots?: { title?: () => any; default?: ( { data, field }: ItemFuncArg<F>, passTrigger?: (cusFields?: string | string[]) => void, passDelayTrigger?: (cusFields?: string | string[], time?: number) => void, ) => any; defaultValue?: any; }; } export interface PFormProps<F extends Recordable = Recordable> extends FormProps { name?: string; items: PFormItemProps<F>[]; customReset?: () => void; } export interface PSearchFormProps<F extends Recordable = Recordable> extends Omit< PFormProps<F>, 'items' > { data: F; items: PFormItemProps<F>[]; loading?: boolean; /** 是否通过 PForm 的原有 reset 流程重置 data,默认 true */ autoReset?: boolean; /** 是否自动追加查询、重置操作项,默认 true */ showActions?: boolean; } export type PGridFormConfig<F extends Recordable = Recordable> = Omit<PFormProps<F>, 'items'> & { /** 查询表单项;传入后自动追加查询、重置按钮,并优先于 items */ searchItems?: PFormItemProps<F>[]; /** 兼容旧用法,按原配置渲染,不自动追加按钮 */ items?: PFormItemProps<F>[]; }; export interface PDescriptionItemProps<D extends Recordable = Recordable> { field?: string; label?: string; span?: number; labelStyle?: Recordable; contentStyle?: Recordable; /** 只读展示渲染器,派发到 renderStore.renderDefault */ readonlyRender?: ItemRender; slots?: { label?: () => any; default?: ({ data, field }: { data: D; field?: string }) => any; }; } export interface PDescriptionProps<D extends Recordable = Recordable> { /** 数据源 */ data: D; items: PDescriptionItemProps<D>[]; /** 透传 a-descriptions */ title?: string; extra?: string; bordered?: boolean; size?: 'default' | 'small' | 'middle'; column?: number | Partial<Record<'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl', number>>; layout?: 'horizontal' | 'vertical'; colon?: boolean; labelStyle?: Recordable; contentStyle?: Recordable; /** 缺省占位,row[field] 为空时展示 */ emptyText?: string; } export interface PBlockProps<F extends Recordable = Recordable> { name?: string; getFormSetting: (data: Partial<F>) => PFormProps<Partial<F>>; source: Partial<F>; } export interface PromisePickerProps< D extends Recordable = Recordable, F extends Recordable = Recordable, > { gridSetting: PGridProps<D, F>; title?: string; width?: string | number; multipleAllowEmpty?: boolean; bodyStyle?: Recordable; beforePick?: (rowOrRows: D | Array<D>) => Promise<void>; } export type GroupMenuItemHandler<F extends Recordable = Recordable> = ({ index, data, code, }: { index: number; code: string; data: Partial<F & { __index: number }>; }) => void; export interface GroupMenuItem<F extends Recordable = Recordable> { content: string; icon?: string; code: string; visibleMethod?: ({ data, index }: { data: Partial<F>; index: number }) => boolean; } export interface PFormGroupProps<F extends Recordable = Recordable> { name?: string; getFormSetting: (data: Partial<F>) => PFormProps<Partial<F>>; title?: string; tabLabel?: string; /** * 获取完整标签页标签 * @param data 数据 * @param idx 实际索引 * @returns 标签页标签 */ getTabLabel?: (data: Partial<F>, idx: number) => string; editAble?: boolean; showAdd?: boolean; /* 是否启用折叠 */ collapsible?: boolean; /** 是否默认折叠 */ defaultCollapsed?: boolean; lazyErrorMark?: boolean; forceRender?: boolean; /* 是否保持连续编号 */ keepSerial?: boolean; loading?: boolean; itemMenus?: Array<GroupMenuItem<F>>; createItem?: ({ list }: { list?: Partial<F>[] }) => Promise<Partial<F>>; max?: number; menuHandler?: GroupMenuItemHandler<F>; } export interface ColumnProps<D extends Recordable = Recordable> extends Omit< TableColumnType, 'slots' > { field?: string; children?: ColumnProps<D>[]; formatter?: | string | [string, ...Array<any>] | ((arg: PartialByKeys<CellFuncArg<D>, 'cellValue'>) => any); slots?: { default?: ({ row, column, rowIndex }: PartialByKeys<CellFuncArg<D>, 'cellValue'>) => any; title?: ({ column }: { column: ColumnProps<D> }) => any; }; cellRender?: CellRender; } export interface PButtonProps extends Omit<ButtonProps, 'type'> { content?: string | (() => any); icon?: string; /** 与 `a-button` 一致,便于模板类型检查 */ type?: ButtonProps['type']; } export interface ToolbarButtonProps extends PButtonProps { code?: string; dropdowns?: ToolbarButtonProps[]; } export interface ToolbarToolProps extends PButtonProps { code: string; } export interface ToolbarConfig { buttons?: Array<ToolbarButtonProps>; tools?: Array<ToolbarToolProps>; disabled?: boolean; } export interface ResponsePathConfig<D extends Recordable = Recordable> { /*非分页取值路径*/ list?: string | ((res: Recordable) => D[]); /*分页取值路径*/ result?: string | ((res: Recordable) => D[]); total?: string | ((res: Recordable) => D[]); /*提示信息取值路径*/ message?: | string | ((res: Recordable) => string | { status: string; content: string; icon?: string }); } export type HandlerMultiDel = (ids: Array<string | number>) => any; export interface AjaxConfig<F extends Recordable = Recordable> { query: (Q: { page?: IPage; form: Partial<F> }) => Promise<Recordable>; multiDelete?: HandlerMultiDel; } export interface ProxyConfig<D extends Recordable = Recordable, F extends Recordable = Recordable> { // 结果集 取值路径 response?: ResponsePathConfig<D>; ajax: AjaxConfig<F>; } export interface PageConfig { pageSizes?: number[]; pageSize?: number; showSizeChanger?: boolean; showQuickJumper?: boolean; } export interface SelectConfig<D extends Recordable = Recordable> { multiple?: boolean; showCount?: boolean; getCheckboxProps?: (record: D) => { disabled?: boolean }; } export type PGridProps<D extends Recordable = Recordable, F extends Recordable = Recordable> = { selectConfig?: SelectConfig<D>; rowKey?: string; striped?: boolean; manualFetch?: boolean; align?: 'left' | 'right' | 'center'; formConfig?: PGridFormConfig<F>; columns?: ColumnProps<D>[]; toolbarConfig?: ToolbarConfig; pageConfig?: PageConfig; proxyConfig?: ProxyConfig<D, F>; tableConfig?: TableProps<D>; scrollMode?: 'outer' | 'inner'; /** * 为 true 时根容器按视口从左上角铺满(与 v-rest 同源),用于外层未声明高度、靠内部撑开的布局。 * 偏移见 `autoBoxSizeOffset`。 */ autoBoxSize?: boolean; /** * `autoBoxSize` 时距视口右侧/底部的预留像素;数字或 `"12px"` 同时作用于两侧;对象可分别指定 `right` / `bottom`。 * 未传时使用 `setUIKitConfig({ grid: { autoBoxSizeOffset } })` 的全局值。 */ autoBoxSizeOffset?: number | string | { right?: number; bottom?: number }; // 重置后不自动提交 lazyReset?: boolean; /** * 表格纵向滚动区额外预留像素:在 `tableWrapper` 高度内扣减表头、底栏后,再从 body 可滚动高度中减去本值,避免末行与滚动条贴边或被裁切。可通过 `setUIKitConfig({ grid: { fitHeight } })` 或组件 `fitHeight` 按项目微调;库内全局默认见 `config`。 */ fitHeight?: number; /** * 适应展示区到页面顶部的canvas渲染高度 通常比table的小 */ fitCanvasHeight?: number; /** * 虚拟列表 Y区计算高度 */ renderY?: number; /** * 适应「外层高度由内容撑开」的布局(典型如弹窗 `PromisePicker`)。 * * 开启后: * - 根容器/表体宿主不再 `flex:1` 强行撑满(避免父无固定高度时塌陷到 0); * - `a-table` 的纵向 `scroll.y` 作为「最多滚动到多少」的上限,由 `renderY` 显式指定; * 若不传 `renderY`,使用基于视口的默认值。内容少时不会出现行区域下方的大片空白。 */ fitContent?: boolean; }; export interface RenderOptions { /** * 渲染器名称 */ name?: string; /** * 目标组件渲染的参数 */ props?: { [key: string]: any }; /** * 目标组件渲染的属性 */ attrs?: { [key: string]: any }; /** * 目标组件渲染的事件 */ events?: { [key: string]: (...args: any[]) => any }; /** * 多目标渲染 */ children?: any[]; /** * 选项 */ options?: IOption[]; /** * 默认值 */ defaultValue?: any; /** * 校验触发器 * @param cusFields field或者field数组 */ handleTrigger?: (cusFields?: string | string[]) => void; /** * 延迟校验触发器 * @param cusFields field或者field数组 * @param time 延迟时间 */ handleDelayTrigger?: (cusFields?: string | string[], time?: number) => void; } export interface RenderFormParams<F extends Recordable = Recordable> { data: F; field?: string; } export interface RenderReadonlyParams<D extends Recordable = Recordable> { data: D; field?: string; title?: string; } export interface RenderTableParams<D extends Recordable = Recordable> { data?: D[]; row: D; rowIndex?: number; field?: string; title?: string; } export interface CanvasColumnProps<T extends Recordable = Recordable> extends Omit< EVirtColumn, 'children' | 'formatter' | 'key' > { key?: string; field?: string; children?: CanvasColumnProps<T>[]; formatter?: | string | [string, ...Array<any>] | ((arg: PartialByKeys<CellFuncArg<T>, 'cellValue'>) => any); slots?: { default?: ({ row, column, rowIndex, }: { row: T; column: CanvasColumnProps<T>; rowIndex: number; }) => any; edit?: ({ row, column, rowIndex, }: { row: T; column: CanvasColumnProps<T>; rowIndex: number; }) => any; title?: ({ column }: { column: CanvasColumnProps<T> }) => any; }; cellRender?: CellRender; editRender?: CellRender; } export interface CanvasTableProps< T extends Recordable = Recordable, B extends Recordable = Recordable, > { columns: CanvasColumnProps<T>[]; data: T[]; config?: ConfigType; footerData?: B[]; loading?: boolean; } export interface PCanvasGridProps< D extends Recordable = Recordable, F extends Recordable = Recordable, > { staticConfig?: { selectable?: boolean; showCount?: boolean; tree?: boolean; }; manualFetch?: boolean; formConfig?: PGridFormConfig<F>; columns: CanvasColumnProps<D>[]; toolbarConfig?: ToolbarConfig; pageConfig?: PageConfig; proxyConfig?: ProxyConfig<D, F>; config?: ConfigType; /** * 表格边框样式,映射 e-virt-table `BORDER`。 * - `true` / `'default'`:完整单元格边框 * - `'outer'`:仅外边框 * - `'inner'` / `false`:仅内部横线 * - `'none'`:无边框 * 显式传入时优先于 `config.BORDER`。 */ border?: BorderConfigValue; /** * 滚动条模式,映射 e-virt-table `scrollbarMode`。 * - `'outer'`:外部预留滚动条轨道(默认) * - `'inner'`:覆盖在内容上,悬停表格内部后显示 * 显式传入时优先于 `config.scrollbarMode`。 */ scrollbarMode?: ScrollbarMode; /** * 内部滚动条(`scrollbarMode: 'inner'`)悬停后显示延迟(ms),映射 `SCROLLBAR_SHOW_DELAY`。 * 显式传入时优先于 `config.SCROLLBAR_SHOW_DELAY`。 */ scrollbarShowDelay?: number; // 重置后不自动提交 lazyReset?: boolean; /** * 适应展示区到页面顶部的高度,通常和容器最上的y值有关(正比) */ fitHeight?: number; /** * 开启后组件根节点按视口从其左上角铺满宽高,与 PGrid 的 autoBoxSize 行为一致。 * 外层未声明固定高度、需组件自身占满可视区域时使用。 */ autoBoxSize?: boolean; /** * `autoBoxSize` 时距视口右侧/底部的预留像素;数字或 `"12px"` 同时作用于两侧;对象可分别指定 `right` / `bottom`。 * 未传时使用 `setUIKitConfig({ grid: { autoBoxSizeOffset } })` 的全局值。 */ autoBoxSizeOffset?: number | string | { right?: number; bottom?: number }; } export interface PGridInstance< D extends Recordable = Recordable, F extends Recordable = Recordable, > { commitProxy: { query: () => Promise<D[]>; reload: () => Promise<D[]>; reloadPage: () => Promise<D[]>; passQuery: (query: Partial<F>, lazy?: boolean) => Promise<void | D[]>; forcePassQuery: (query: Partial<F>, lazy?: boolean) => Promise<void | D[]>; }; selectedRowKeys: string[] | number[]; selectedRecords: D[]; $table: Recordable; $form: Recordable; getFormData: () => Partial<F>; setLoadings: (value: boolean) => void; setBtnLoading: (code: string, status: boolean) => void; resizeTable: () => void; } export interface PFormInstance { reset: () => void; $form: Recordable; } export interface PromisePickerInstance<D extends Recordable = Recordable> { pick: () => Promise<{ row: D; field?: string }>; pickMultiple: () => Promise<D[]>; grid: PGridInstance<D>; hide: () => void; } export interface PFormBlockInstance { $form: Recordable; } export interface PFormGroupInstance { activeKey: number; setActiveKey: (activeKey: number) => void; /** 按数组下标删除一项,并清理校验缓存 / 激活态 */ removeItem: (index: number) => void; validateAll: () => Promise<void>; validate: (index: number, ignoreTabError?: boolean) => Promise<void>; validateFields: (index: number, fields: string[], ignoreTabError?: boolean) => Promise<void>; collapse: () => void; expand: () => void; } export interface PCanvasTableInstance<T extends Recordable = Recordable> { $table: InstanceType<typeof EVirtTable>; selectedRecords: T[]; clearSelection: () => void; setLoading: (value: boolean) => void; }