@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
1 lines • 9.29 kB
Source Map (JSON)
{"version":3,"file":"ChatItem.mjs","names":["chatMessages","Flexbox","Avatar","Title","ErrorContent","MessageContent","Actions","BorderSpacing"],"sources":["../../../src/chat/ChatItem/ChatItem.tsx"],"sourcesContent":["'use client';\n\nimport { cx, useResponsive } from 'antd-style';\nimport { memo, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { Flexbox } from '@/Flex';\nimport chatMessages from '@/i18n/resources/en/chat';\nimport { useTranslation } from '@/i18n/useTranslation';\n\nimport Actions from './components/Actions';\nimport Avatar from './components/Avatar';\nimport BorderSpacing from './components/BorderSpacing';\nimport ErrorContent from './components/ErrorContent';\nimport MessageContent from './components/MessageContent';\nimport Title from './components/Title';\nimport { styles } from './style';\nimport type { ChatItemProps } from './type';\n\nconst MOBILE_AVATAR_SIZE = 32;\n\nconst ChatItem = memo<ChatItemProps>(\n ({\n avatarAddon,\n onAvatarClick,\n avatarProps,\n actions,\n className,\n primary,\n loading,\n message,\n placeholderMessage,\n placement = 'left',\n variant = 'bubble',\n avatar,\n error,\n showTitle,\n time,\n editing,\n onChange,\n onEditingChange,\n messageExtra,\n renderMessage,\n text,\n errorMessage,\n onDoubleClick,\n fontSize,\n aboveMessage,\n belowMessage,\n markdownProps,\n actionsWrapWidth = 54,\n showAvatar = true,\n titleAddon,\n ...rest\n }) => {\n const { mobile } = useResponsive();\n const { t } = useTranslation(chatMessages);\n\n const avatarSize = mobile ? MOBILE_AVATAR_SIZE : avatarProps?.size || 40;\n const cssVariables = useMemo<Record<string, string>>(\n () => ({\n '--chat-item-avatar-size': `${avatarSize}px`,\n }),\n [avatarSize],\n );\n\n const hasTime = Boolean(time);\n const placeholderText = placeholderMessage ?? t('chat.placeholder');\n const avatarAlt = avatarProps?.alt || avatar.title || t('chat.avatar');\n\n // 在 ChatItem 组件中添加\n const contentRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const [layoutMode, setLayoutMode] = useState<'horizontal' | 'vertical'>(\n variant === 'bubble' ? 'horizontal' : 'vertical',\n );\n\n // 使用 ResizeObserver 监控内容和容器尺寸\n useEffect(() => {\n if (variant === 'docs') {\n setLayoutMode('vertical');\n return;\n }\n\n if (!contentRef.current || !containerRef.current) return;\n\n const observer = new ResizeObserver(() => {\n if (!contentRef.current || !containerRef.current) return;\n\n const containerWidth = containerRef.current.clientWidth;\n const contentWidth = contentRef.current.scrollWidth; // 使用scrollWidth获取实际内容宽度\n\n // 预留给Actions的最小空间 (根据实际Actions大小调整)\n\n // 只有当内容宽度 + Actions最小宽度 > 容器宽度时才切换布局\n setLayoutMode(contentWidth + actionsWrapWidth > containerWidth ? 'vertical' : 'horizontal');\n });\n\n observer.observe(contentRef.current);\n observer.observe(containerRef.current);\n\n return () => observer.disconnect();\n }, [variant, actionsWrapWidth]);\n\n const containerClassName = cx(\n variant === 'docs' ? styles.containerDocs : styles.container,\n className,\n );\n\n const messageContainerClassName = useMemo(() => {\n if (editing) {\n return hasTime ? styles.messageContainerEditingWithTime : styles.messageContainerEditing;\n }\n return hasTime ? styles.messageContainerWithTime : styles.messageContainer;\n }, [editing, hasTime]);\n\n const messageContentClassName = useMemo(() => {\n return editing ? styles.messageContentEditing : styles.messageContent;\n }, [editing]);\n\n return (\n <Flexbox\n className={containerClassName}\n direction={placement === 'left' ? 'horizontal' : 'horizontal-reverse'}\n gap={mobile ? 6 : 12}\n style={cssVariables}\n {...rest}\n >\n {showAvatar && (\n <Avatar\n {...avatarProps}\n addon={avatarAddon}\n alt={avatarAlt}\n avatar={avatar}\n loading={loading}\n onClick={onAvatarClick}\n placement={placement}\n size={avatarSize}\n style={{\n marginTop: showTitle ? -12 : 6,\n ...avatarProps?.style,\n }}\n />\n )}\n <Flexbox\n align={placement === 'left' ? 'flex-start' : 'flex-end'}\n className={messageContainerClassName}\n ref={containerRef}\n >\n <Title\n avatar={avatar}\n placement={placement}\n showTitle={showTitle}\n time={time}\n titleAddon={titleAddon}\n />\n {aboveMessage}\n <Flexbox\n align={placement === 'left' ? 'flex-start' : 'flex-end'}\n className={messageContentClassName}\n data-layout={layoutMode} // 添加数据属性以方便样式选择\n direction={\n layoutMode === 'horizontal'\n ? placement === 'left'\n ? 'horizontal'\n : 'horizontal-reverse'\n : 'vertical'\n }\n gap={8}\n >\n <Flexbox ref={contentRef} width={'100%'}>\n {error && (message === placeholderText || !message) ? (\n <ErrorContent error={error} message={errorMessage} placement={placement} />\n ) : (\n <MessageContent\n editing={editing}\n fontSize={fontSize}\n markdownProps={markdownProps}\n message={message}\n messageExtra={\n <>\n {error && (\n <ErrorContent error={error} message={errorMessage} placement={placement} />\n )}\n {messageExtra}\n </>\n }\n onChange={onChange}\n onDoubleClick={onDoubleClick}\n onEditingChange={onEditingChange}\n placement={placement}\n primary={primary}\n renderMessage={renderMessage}\n text={text}\n variant={variant}\n />\n )}\n </Flexbox>\n {actions && (\n <Actions\n actions={actions}\n editing={editing}\n placement={placement}\n variant={variant}\n />\n )}\n </Flexbox>\n {belowMessage}\n </Flexbox>\n {mobile && variant === 'bubble' && showAvatar && (\n <BorderSpacing borderSpacing={MOBILE_AVATAR_SIZE} />\n )}\n </Flexbox>\n );\n },\n);\n\nexport default ChatItem;\n\nexport type { ChatItemProps } from './type';\n"],"mappings":"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"}