UNPKG

@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
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 }; };