@douyinfe/semi-ui
Version:
A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.
139 lines (138 loc) • 5.1 kB
TypeScript
import type { ReactNode, ClipboardEvent as ReactClipboardEvent } from "react";
import { OnChangeProps, UploadProps } from "../upload";
import { TooltipProps } from "../tooltip";
import { BaseSkill, Reference, Suggestion, Attachment, Content, LeftMenuChangeProps, RichTextJSON, MessageContent } from '@douyinfe/semi-foundation/lib/es/aiChatInput/interface';
import { Editor, Extensions } from "@tiptap/core";
import { Content as TiptapContent } from "@tiptap/core";
import { PopoverProps } from "../popover";
export * from '@douyinfe/semi-foundation/lib/es/aiChatInput/interface';
import { Node } from '@tiptap/pm/model';
export interface AIChatInputState {
templateVisible: boolean;
skillVisible: boolean;
suggestionVisible: boolean;
attachments?: Attachment[];
skill?: Skill;
popupWidth?: number;
activeSkillIndex?: number;
activeSuggestionIndex?: number;
popupKey?: number;
content?: RichTextJSON;
richTextInit?: boolean;
}
export type PlaceholderProps = string | ((props: {
editor: Editor;
node: Node;
pos: number;
hasAnchor: boolean;
}) => string);
export interface AIChatInputProps {
dropdownMatchTriggerWidth?: boolean;
keepSkillAfterSend: boolean;
className?: string;
style?: React.CSSProperties;
placeholder?: PlaceholderProps;
/**
* Whether to show placeholder when only skill is selected (no other content)
* @default false
*/
showPlaceholderWhenSkillOnly?: boolean;
extensions?: Extensions;
onContentChange?: (contents: Content[]) => void;
defaultContent?: TiptapContent;
onFocus?: (event: React.FocusEvent) => void;
onBlur?: (event: React.FocusEvent) => void;
/**
* Listen to paste event on input editor
*
* Note: This is a clipboard event callback and does not change default paste behavior.
*/
onPaste?: (event: ReactClipboardEvent<HTMLDivElement>) => void;
references?: Reference[];
renderReference?: (reference: Reference) => ReactNode;
onReferenceDelete?: (reference: Reference) => void;
onReferenceClick?: (reference: Reference) => void;
uploadProps?: UploadProps;
onUploadChange?: (props: OnChangeProps) => void;
/**
* Customize upload button UI in footer action area,
* while keeping built-in upload / paste-upload logic.
*/
renderUploadButton?: (props: RenderUploadButtonProps) => ReactNode;
renderTopSlot?: (props: RenderTopSlotProps) => ReactNode;
topSlotPosition?: 'top' | 'middle' | 'bottom';
showUploadFile?: boolean;
showReference?: boolean;
showUploadButton?: boolean;
round?: boolean;
canSend?: boolean;
onMessageSend?: (props: MessageContent) => void;
onStopGenerate?: () => void;
uploadTipProps?: TooltipProps;
generating?: boolean;
renderConfigureArea?: (className?: string) => ReactNode;
onConfigureChange?: (value: LeftMenuChangeProps, changedValue: LeftMenuChangeProps) => void;
renderActionArea?: (props: ActionAreaProps) => ReactNode;
suggestions?: Suggestion[];
renderSuggestionItem?: (props: RenderSuggestionItemProps) => ReactNode;
onSuggestClick?: (suggestion: Suggestion) => void;
skills?: Skill[];
skillHotKey?: string;
templatesStyle?: React.CSSProperties;
templatesCls?: string;
onSkillChange?: (skill: Skill) => void;
renderSkillItem?: (props: RenderSkillItemProps) => ReactNode;
renderTemplate?: (skill: Skill, onTemplateClick: (content: string) => void) => ReactNode;
onTemplateVisibleChange?: (visible: boolean) => void;
showTemplateButton?: boolean;
transformer?: Map<string, (obj: any) => any>;
popoverProps?: PopoverProps;
sendHotKey?: 'enter' | 'shift+enter';
immediatelyRender?: boolean;
/**
* Whether to clear input content when generating state changes from false to true
* @default true
*/
clearContentOnGenerating?: boolean;
}
export interface RenderUploadButtonProps {
/**
* Default upload button node rendered by AIChatInput.
* You can wrap/clone it or return a completely custom node.
*/
defaultNode: ReactNode;
/**
* Open file selector dialog.
* Note: Upload wrapper will also open dialog on click by default,
* but you can use this when you stop propagation in your custom node.
*/
openFileDialog: () => void;
disabled: boolean;
attachments: Attachment[];
}
export interface RenderSuggestionItemProps {
suggestion: Suggestion;
className: string;
onClick: () => void;
onMouseEnter: () => void;
}
export interface RenderSkillItemProps {
skill: Skill;
className: string;
onClick: () => void;
onMouseEnter: () => void;
}
export interface Skill extends BaseSkill {
icon?: ReactNode;
}
interface ActionAreaProps {
menuItem: ReactNode[];
className: string;
}
interface RenderTopSlotProps {
references: Reference[];
attachments: Attachment[];
content: Content[];
handleUploadFileDelete: (attachment: Attachment) => void;
handleReferenceDelete: (reference: Reference) => void;
}