@plteam/chat-ui
Version:
CUI Kit is a free and open-source library for creating AI assistant chat interfaces, built with React, Material UI, and TypeScript
135 lines (134 loc) • 7.13 kB
JavaScript
import * as React from 'react';
import { MockComponent } from '../utils/MockComponent';
import ListItemText from '@mui/material/ListItemText';
import Button from '@mui/material/Button';
import IconButton from '@mui/material/IconButton';
import Link from '@mui/material/Link';
import TableHead from '@mui/material/TableHead';
import TableBody from '@mui/material/TableBody';
import TableRow from '@mui/material/TableRow';
import Typography from '@mui/material/Typography';
import MessageMarkdownTable from '../message/markdown/MessageMarkdownTable';
import MessageMarkdownTableCell from '../message/markdown/MessageMarkdownTableCell';
import { ChatMessageOl, MessageMarkdownUl } from '../message/markdown/MessageMarkdownUl';
import MessageMarkdownImage from '../message/markdown/MessageMarkdownImage';
import MessagePagination from '../message/MessagePagination';
import Stack from '@mui/material/Stack';
import MessageAssistantStatus from '../message/MessageAssistantStatus';
import MdMenuItem from '../../ui/menu/MdMenuItem';
import InitialThreadMessage from '../thread/InitialThreadMessage';
import MessageMarkdownCode from '../message/markdown/MessageMarkdownCode';
import MessageMarkdownBlockquote from '../message/markdown/MessageMarkdownBlockquote';
import MessageMarkdownCodeWrapper from '../message/markdown/MessageMarkdownCodeWrapper';
import { chatIconSlots } from './ChatIconSlots';
import ThreadRootContainer from '../thread/ThreadRootContainer';
import ChatTextFieldRowInner from '../form/ChatTextFieldRowInner';
import { ChatMarkdownBlockRoot } from '../message/markdown/MessageMarkdownBlock';
import { ChatMarkdownReasoningBlockRoot } from '../message/reasoning/MessageReasoningFull';
import MessageMarkdownWrapper from '../message/markdown/MessageMarkdownWrapper';
import Chip from '@mui/material/Chip';
import Divider from '@mui/material/Divider';
import { PreviewErrorBox, PreviewItemBox } from '../form/preview/PreviewItemContainer';
import FileAttachmentButton from '../form/attachments/FileAttachmentButton';
import ListItemButton from '@mui/material/ListItemButton';
import MessageEditInput from '../form/MessageEditInput';
import ThreadInputWrapper from '../form/ThreadInputWrapper';
import PlayIcon from '../form/preview/PlayIcon';
export const getMarkdownSlots = (slots) => ({
markdownWrapper: slots?.markdownWrapper ?? MessageMarkdownWrapper,
markdownMessageRoot: slots?.markdownMessageRoot ?? ChatMarkdownBlockRoot,
markdownReasoningRoot: slots?.markdownReasoningRoot ?? ChatMarkdownReasoningBlockRoot,
markdownA: slots?.markdownA ?? Link,
markdownTable: slots?.markdownTable ?? MessageMarkdownTable,
markdownThead: slots?.markdownThead ?? TableHead,
markdownTbody: slots?.markdownTbody ?? TableBody,
markdownTh: slots?.markdownTh ?? MessageMarkdownTableCell,
markdownTd: slots?.markdownTd ?? MessageMarkdownTableCell,
markdownTdText: slots?.markdownTdText ?? Typography,
markdownTr: slots?.markdownTr ?? TableRow,
markdownSpan: slots?.markdownSpan ?? Typography,
markdownUl: slots?.markdownUl ?? MessageMarkdownUl,
markdownOl: slots?.markdownOl ?? ChatMessageOl,
markdownH1: slots?.markdownH1 ?? Typography,
markdownH2: slots?.markdownH2 ?? Typography,
markdownH3: slots?.markdownH3 ?? Typography,
markdownH4: slots?.markdownH4 ?? Typography,
markdownH5: slots?.markdownH5 ?? Typography,
markdownH6: slots?.markdownH6 ?? Typography,
markdownImg: slots?.markdownImg ?? MessageMarkdownImage,
markdownCodeWrapper: slots?.markdownCodeWrapper ?? MessageMarkdownCodeWrapper,
markdownCode: slots?.markdownCode ?? MessageMarkdownCode,
markdownHr: slots?.markdownHr ?? Divider,
markdownBlockquote: slots?.markdownBlockquote ?? MessageMarkdownBlockquote,
markdownP: slots?.markdownP ?? Typography,
});
export const getMarkdownSlotProps = (slotProps) => ({
markdownH1: { variant: 'h1' },
markdownH2: { variant: 'h2' },
markdownH3: { variant: 'h3' },
markdownH4: { variant: 'h4' },
markdownH5: { variant: 'h5' },
markdownH6: { variant: 'h6' },
markdownCodeWrapper: {
dir: 'ltr',
...slotProps?.markdownCodeWrapper,
},
...slotProps,
});
export const usePropsSlots = (usersProps) => {
const { coreSlots, slots, slotProps } = usersProps;
const res = React.useMemo(() => {
const core = {
button: coreSlots?.button ?? Button,
iconButton: coreSlots?.iconButton ?? IconButton,
chip: coreSlots?.chip ?? Chip,
// TODO: Props error
listItemText: coreSlots?.listItemText ?? ListItemText,
menuItem: coreSlots?.menuItem ?? MdMenuItem,
listItemButton: coreSlots?.listItemButton ?? ListItemButton,
};
const componentSlots = {
...chatIconSlots,
...slots,
firstMessage: slots?.firstMessage ?? InitialThreadMessage,
thread: slots?.thread ?? ThreadRootContainer,
sendMessageButton: slots?.sendMessageButton ?? core.iconButton,
threadInputWrapper: slots?.threadInputWrapper ?? ThreadInputWrapper,
threadInput: slots?.threadInput ?? ChatTextFieldRowInner,
messageEditInput: slots?.messageEditInput ?? MessageEditInput,
attachmentPreviewItem: slots?.attachmentPreviewItem ?? PreviewItemBox,
attachmentPreviewError: slots?.attachmentPreviewError ?? PreviewErrorBox,
attachmentFormButton: slots?.attachmentFormButton ?? FileAttachmentButton,
aiModelButton: slots?.aiModelButton ?? Button,
attachmentVideoPlayIcon: slots?.attachmentVideoPlayIcon ?? PlayIcon,
// MARKDOWN
...getMarkdownSlots(slots),
messagePagination: slots?.messagePagination ?? MessagePagination,
messagePaginationRoot: slots?.messagePaginationRoot ?? Stack,
messagePaginationButton: slots?.messagePaginationButton ?? core.iconButton,
messageRatingButton: slots?.messageRatingButton ?? core.iconButton,
messagePaginationText: slots?.messagePaginationText ?? Typography,
messageAssistantFooter: slots?.messageAssistantFooter ?? MockComponent,
messageAssistantStatus: slots?.messageAssistantStatus ?? MessageAssistantStatus,
messageAssistantStatusText: slots?.messageAssistantStatusText ?? Typography,
messageAssistantReasoningTitle: slots?.messageAssistantReasoningTitle ?? Typography,
};
return {
slots: componentSlots,
coreSlots: core,
};
}, [slots]);
const componentSlotProps = React.useMemo(() => ({
...getMarkdownSlotProps(slotProps),
...slotProps,
markdownCodeWrapper: {
dir: 'ltr',
...slotProps?.markdownCodeWrapper,
},
}), [slotProps]);
return {
slotProps: componentSlotProps,
slots: res.slots,
coreSlots: res.coreSlots
};
};