UNPKG

ant-design-x-vue-next

Version:

Ant Design X for Vue — community continuation aligned with @ant-design/x

176 lines (175 loc) 6.85 kB
import type { AvatarProps, DividerProps } from 'ant-design-vue'; import type { AvoidValidation } from '../type-utility'; import type { CSSProperties, HTMLAttributes, VNode, VNodeChild } from 'vue'; import { AnyObject } from '../_util/type'; import type { MessageStatus } from '../use-x-chat/use-x-chat'; export interface EditableBubbleOption { editing?: boolean; okText?: VNodeChild; cancelText?: VNodeChild; } export type BubbleTypingEffect = 'typing' | 'fade-in'; export type FooterPlacement = 'outer-start' | 'outer-end' | 'inner-start' | 'inner-end'; export interface TypingOption { /** * 每次前进字符数;数组表示闭区间内随机步长 * @default 1 */ step?: number | [number, number]; /** * @default 50 */ interval?: number; /** * @default null */ suffix?: VNode | string; /** * 打字动画效果:`typing` 光标逐字;`fade-in` 片段淡入 * @default 'typing' */ effect?: BubbleTypingEffect; /** * 内容增长时是否保留公共前缀(流式场景) * @default true */ keepPrefix?: boolean; } /** Align React Bubble SemanticType. */ export type SemanticType = 'root' | 'body' | 'avatar' | 'content' | 'header' | 'footer' | 'extra'; export type BubbleSemanticType = SemanticType; export type BubbleContentType = VNode | string | AnyObject | number; export type InfoType = { key?: string | number; status?: MessageStatus; extraInfo?: AnyObject; }; /** @deprecated Prefer `InfoType` */ export type SlotInfoType = InfoType; export interface _AvatarProps extends AvatarProps { class: string; style: CSSProperties; } export interface BubbleProps<ContentType extends BubbleContentType = string> extends /* @vue-ignore */ Omit<HTMLAttributes, 'content'> { prefixCls?: string; rootClassName?: string; styles?: Partial<Record<SemanticType, CSSProperties>>; classNames?: Partial<Record<SemanticType, string>>; /** * Avatar — props object, VNode, or BubbleSlot `(content, info) => VNode`. * Zero-arg `() => VNode` remains supported. */ avatar?: AvoidValidation<Partial<_AvatarProps> | VNode | ((content: ContentType, info: InfoType) => VNode | string) | (() => VNode)>; placement?: 'start' | 'end'; loading?: boolean; typing?: AvoidValidation<TypingOption | boolean | ((content: ContentType, info: InfoType) => TypingOption | boolean)>; /** * 是否处于流式传输;为 true 时不触发 onTypingComplete * @default false */ streaming?: boolean; content?: ContentType; /** * Custom content renderer (React 2.x API). */ contentRender?: (content: ContentType, info: InfoType) => VNode | string; /** * @deprecated Prefer `contentRender` */ messageRender?: (content: ContentType, info?: InfoType) => VNode | string; loadingRender?: () => VNode; /** Message status — used by list / contentRender info (not a DOM attr). */ status?: MessageStatus; /** Extra metadata for contentRender info (not a DOM attr). */ extraInfo?: AnyObject; variant?: 'filled' | 'borderless' | 'outlined' | 'shadow'; shape?: 'round' | 'corner'; _key?: number | string; /** * 打字过程回调(rendererContent 为当前已渲染片段,currentContent 为完整内容) */ onTyping?: (rendererContent: string, currentContent: string) => void; onTypingComplete?: VoidFunction; header?: AvoidValidation<VNode | string | ((content: ContentType, info: InfoType) => VNode | string)>; footer?: AvoidValidation<VNode | string | ((content: ContentType, info: InfoType) => VNode | string)>; /** * Side UI beside the bubble body (timestamp / Actions). Distinct from `extraInfo` metadata. */ extra?: AvoidValidation<VNode | string | ((content: ContentType, info: InfoType) => VNode | string)>; /** * footer 渲染位置 * @default placement===start ? 'outer-start' : 'outer-end' */ footerPlacement?: FooterPlacement; /** * 是否可编辑(仅 content 为 string) */ editable?: boolean | EditableBubbleOption; onEditConfirm?: (content: string) => void; onEditCancel?: () => void; } export type SystemBubbleProps<ContentType extends BubbleContentType = string> = Pick<BubbleProps<ContentType>, 'prefixCls' | 'content' | 'rootClassName' | 'variant' | 'shape' | 'styles' | 'classNames'>; export interface DividerBubbleProps<ContentType extends BubbleContentType = string> { prefixCls?: string; rootClassName?: string; styles?: BubbleProps<ContentType>['styles']; classNames?: BubbleProps<ContentType>['classNames']; content?: ContentType; dividerProps?: Omit<DividerProps, 'children'>; } export interface BubbleRef { nativeElement: HTMLElement; } export interface BubbleContextProps { onUpdate?: VoidFunction; key?: string | number; status?: MessageStatus; extraInfo?: AnyObject; } export interface BubbleListRef { /** Outer list root (`.ant-bubble-list`). */ nativeElement: HTMLDivElement; /** Scrollable box (`.ant-bubble-list-scroll-box`). */ scrollBoxNativeElement: HTMLDivElement; scrollTo: (info: { /** * Scroll position. Prefer React-aligned `top`. * @deprecated Use `top` instead. */ offset?: number; /** Scroll offset, or visual `'top'` / `'bottom'`. */ top?: number | 'bottom' | 'top'; key?: string | number; behavior?: ScrollBehavior; block?: ScrollLogicalPosition; }) => void; } export type BubbleDataType = BubbleProps<any> & { key?: string | number; role?: string; status?: MessageStatus; extraInfo?: AnyObject; }; /** Align React `@ant-design/x` export name for Bubble.List items. */ export type BubbleItemType = BubbleDataType; export type RoleType = Partial<Omit<BubbleProps<any>, 'content'>>; export type RolesType = Record<string, RoleType> | ((bubbleDataP: BubbleDataType, index: number) => RoleType); /** Align React Bubble.List SemanticType. */ export type ListSemanticType = SemanticType | 'root' | 'scroll' | 'bubble' | 'system' | 'divider'; export interface BubbleListProps extends /* @vue-ignore */ Omit<HTMLAttributes, 'role'> { prefixCls?: string; rootClassName?: string; items?: BubbleDataType[]; autoScroll?: boolean; /** * Vue 历史命名;与 React `role` 等价。两者同时传入时优先 `roles`。 */ roles?: AvoidValidation<RolesType>; /** * 对齐 React Bubble.List `role`:按 `items[].role` 映射默认气泡属性。 */ role?: AvoidValidation<RolesType>; onScroll?: (e: Event) => void; classNames?: Partial<Record<ListSemanticType, string>>; styles?: Partial<Record<ListSemanticType, CSSProperties>>; }