@huyooo/ai-chat-frontend-react 0.2.14 → 0.2.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/index.css +0 -1
  2. package/dist/index.js +1 -5418
  3. package/package.json +4 -5
  4. package/dist/index.css.map +0 -1
  5. package/dist/index.js.map +0 -1
  6. package/src/adapter.ts +0 -68
  7. package/src/components/ChatPanel.tsx +0 -553
  8. package/src/components/common/ConfirmDialog.css +0 -136
  9. package/src/components/common/ConfirmDialog.tsx +0 -91
  10. package/src/components/common/CopyButton.css +0 -22
  11. package/src/components/common/CopyButton.tsx +0 -46
  12. package/src/components/common/IndexingSettings.css +0 -207
  13. package/src/components/common/IndexingSettings.tsx +0 -398
  14. package/src/components/common/SettingsPanel.css +0 -337
  15. package/src/components/common/SettingsPanel.tsx +0 -215
  16. package/src/components/common/Toast.css +0 -50
  17. package/src/components/common/Toast.tsx +0 -38
  18. package/src/components/common/ToggleSwitch.css +0 -52
  19. package/src/components/common/ToggleSwitch.tsx +0 -20
  20. package/src/components/header/ChatHeader.css +0 -285
  21. package/src/components/header/ChatHeader.tsx +0 -376
  22. package/src/components/input/AtFilePicker.css +0 -147
  23. package/src/components/input/AtFilePicker.tsx +0 -519
  24. package/src/components/input/ChatInput.css +0 -283
  25. package/src/components/input/ChatInput.tsx +0 -575
  26. package/src/components/input/DropdownSelector.css +0 -231
  27. package/src/components/input/DropdownSelector.tsx +0 -333
  28. package/src/components/input/ImagePreviewModal.css +0 -124
  29. package/src/components/input/ImagePreviewModal.tsx +0 -118
  30. package/src/components/input/at-views/AtBranchView.tsx +0 -34
  31. package/src/components/input/at-views/AtBrowserView.tsx +0 -34
  32. package/src/components/input/at-views/AtChatsView.tsx +0 -34
  33. package/src/components/input/at-views/AtDocsView.tsx +0 -34
  34. package/src/components/input/at-views/AtFilesView.tsx +0 -168
  35. package/src/components/input/at-views/AtTerminalsView.tsx +0 -34
  36. package/src/components/input/at-views/AtViewStyles.css +0 -143
  37. package/src/components/input/at-views/index.ts +0 -9
  38. package/src/components/message/ContentRenderer.css +0 -9
  39. package/src/components/message/MessageBubble.css +0 -193
  40. package/src/components/message/MessageBubble.tsx +0 -240
  41. package/src/components/message/PartsRenderer.css +0 -12
  42. package/src/components/message/PartsRenderer.tsx +0 -168
  43. package/src/components/message/WelcomeMessage.css +0 -221
  44. package/src/components/message/WelcomeMessage.tsx +0 -93
  45. package/src/components/message/parts/CollapsibleCard.css +0 -80
  46. package/src/components/message/parts/CollapsibleCard.tsx +0 -80
  47. package/src/components/message/parts/ErrorPart.css +0 -9
  48. package/src/components/message/parts/ErrorPart.tsx +0 -40
  49. package/src/components/message/parts/ImagePart.css +0 -49
  50. package/src/components/message/parts/ImagePart.tsx +0 -54
  51. package/src/components/message/parts/SearchPart.css +0 -44
  52. package/src/components/message/parts/SearchPart.tsx +0 -63
  53. package/src/components/message/parts/TextPart.css +0 -579
  54. package/src/components/message/parts/TextPart.tsx +0 -213
  55. package/src/components/message/parts/ThinkingPart.css +0 -9
  56. package/src/components/message/parts/ThinkingPart.tsx +0 -48
  57. package/src/components/message/parts/ToolCallPart.css +0 -246
  58. package/src/components/message/parts/ToolCallPart.tsx +0 -289
  59. package/src/components/message/parts/ToolResultPart.css +0 -67
  60. package/src/components/message/parts/index.ts +0 -13
  61. package/src/components/message/parts/visual-predicate.ts +0 -43
  62. package/src/components/message/parts/visual-render.ts +0 -19
  63. package/src/components/message/parts/visual.ts +0 -12
  64. package/src/components/message/welcome-types.ts +0 -46
  65. package/src/context/AutoRunConfigContext.tsx +0 -13
  66. package/src/context/ChatAdapterContext.tsx +0 -8
  67. package/src/context/ChatInputContext.tsx +0 -40
  68. package/src/context/RenderersContext.tsx +0 -35
  69. package/src/hooks/useChat.ts +0 -1569
  70. package/src/hooks/useImageUpload.ts +0 -345
  71. package/src/hooks/useVoiceInput.ts +0 -454
  72. package/src/hooks/useVoiceToTextInput.ts +0 -87
  73. package/src/index.ts +0 -151
  74. package/src/styles.css +0 -330
  75. package/src/types/index.ts +0 -196
  76. package/src/utils/fileIcon.ts +0 -49
@@ -1,118 +0,0 @@
1
- import { useCallback, useEffect, useState } from 'react'
2
- import { createPortal } from 'react-dom'
3
- import { Icon } from '@iconify/react'
4
- import './ImagePreviewModal.css'
5
-
6
- interface ImagePreviewModalProps {
7
- visible: boolean
8
- images: string[]
9
- initialIndex?: number
10
- onClose: () => void
11
- onIndexChange?: (index: number) => void
12
- }
13
-
14
- export function ImagePreviewModal({
15
- visible,
16
- images,
17
- initialIndex = 0,
18
- onClose,
19
- onIndexChange,
20
- }: ImagePreviewModalProps) {
21
- const [currentIndex, setCurrentIndex] = useState(initialIndex)
22
-
23
- // 重置索引
24
- useEffect(() => {
25
- if (visible) {
26
- setCurrentIndex(initialIndex)
27
- }
28
- }, [visible, initialIndex])
29
-
30
- // 通知父组件索引变化
31
- useEffect(() => {
32
- onIndexChange?.(currentIndex)
33
- }, [currentIndex, onIndexChange])
34
-
35
- // 上一张
36
- const prev = useCallback(() => {
37
- if (currentIndex > 0) {
38
- setCurrentIndex(currentIndex - 1)
39
- }
40
- }, [currentIndex])
41
-
42
- // 下一张
43
- const next = useCallback(() => {
44
- if (currentIndex < images.length - 1) {
45
- setCurrentIndex(currentIndex + 1)
46
- }
47
- }, [currentIndex, images.length])
48
-
49
- // 键盘导航
50
- useEffect(() => {
51
- if (!visible) return
52
- const handleKeyDown = (e: KeyboardEvent) => {
53
- if (e.key === 'Escape') {
54
- onClose()
55
- } else if (e.key === 'ArrowLeft') {
56
- prev()
57
- } else if (e.key === 'ArrowRight') {
58
- next()
59
- }
60
- }
61
- document.addEventListener('keydown', handleKeyDown)
62
- return () => document.removeEventListener('keydown', handleKeyDown)
63
- }, [visible, onClose, prev, next])
64
-
65
- if (!visible) return null
66
-
67
- const currentSrc = images[currentIndex] || ''
68
-
69
- return createPortal(
70
- <div className="image-preview-modal" onClick={onClose}>
71
- {/* 顶部栏 */}
72
- <div className="preview-header" onClick={(e) => e.stopPropagation()}>
73
- {images.length > 1 && (
74
- <div className="preview-counter">
75
- {currentIndex + 1} / {images.length}
76
- </div>
77
- )}
78
- <button className="preview-close-btn" title="关闭 (Esc)" onClick={onClose}>
79
- <Icon icon="lucide:x" width={18} />
80
- </button>
81
- </div>
82
-
83
- {/* 左导航 */}
84
- {images.length > 1 && (
85
- <button
86
- className={`preview-nav-btn preview-nav-prev${currentIndex <= 0 ? ' disabled' : ''}`}
87
- disabled={currentIndex <= 0}
88
- onClick={(e) => {
89
- e.stopPropagation()
90
- prev()
91
- }}
92
- >
93
- <Icon icon="lucide:chevron-left" width={20} />
94
- </button>
95
- )}
96
-
97
- {/* 主图片区域 */}
98
- <div className="preview-main" onClick={(e) => e.stopPropagation()}>
99
- <img src={currentSrc} alt="预览" className="preview-image" />
100
- </div>
101
-
102
- {/* 右导航 */}
103
- {images.length > 1 && (
104
- <button
105
- className={`preview-nav-btn preview-nav-next${currentIndex >= images.length - 1 ? ' disabled' : ''}`}
106
- disabled={currentIndex >= images.length - 1}
107
- onClick={(e) => {
108
- e.stopPropagation()
109
- next()
110
- }}
111
- >
112
- <Icon icon="lucide:chevron-right" width={20} />
113
- </button>
114
- )}
115
- </div>,
116
- document.body
117
- )
118
- }
@@ -1,34 +0,0 @@
1
- import { forwardRef, useImperativeHandle } from 'react'
2
- import { Icon } from '@iconify/react'
3
- import './AtViewStyles.css'
4
-
5
- export interface AtPlaceholderViewProps {
6
- query: string
7
- activeIndex: number
8
- onSelect: (path: string) => void
9
- onSetActive: (index: number) => void
10
- onUpdateCount: (count: number) => void
11
- }
12
-
13
- export interface AtPlaceholderViewHandle {
14
- getActivePath: () => string | null
15
- confirmActive: () => void
16
- }
17
-
18
- export const AtBranchView = forwardRef<AtPlaceholderViewHandle, AtPlaceholderViewProps>((_, ref) => {
19
- useImperativeHandle(ref, () => ({
20
- getActivePath: () => null,
21
- confirmActive: () => {},
22
- }), [])
23
-
24
- return (
25
- <div className="at-placeholder-view">
26
- <Icon icon="lucide:git-branch" width={32} className="at-placeholder-icon" />
27
- <div className="at-placeholder-title">分支差异</div>
28
- <div className="at-placeholder-desc">功能待实现</div>
29
- <div className="at-placeholder-hint">将支持引用当前分支与主分支的差异</div>
30
- </div>
31
- )
32
- })
33
-
34
- AtBranchView.displayName = 'AtBranchView'
@@ -1,34 +0,0 @@
1
- import { forwardRef, useImperativeHandle } from 'react'
2
- import { Icon } from '@iconify/react'
3
- import './AtViewStyles.css'
4
-
5
- export interface AtPlaceholderViewProps {
6
- query: string
7
- activeIndex: number
8
- onSelect: (path: string) => void
9
- onSetActive: (index: number) => void
10
- onUpdateCount: (count: number) => void
11
- }
12
-
13
- export interface AtPlaceholderViewHandle {
14
- getActivePath: () => string | null
15
- confirmActive: () => void
16
- }
17
-
18
- export const AtBrowserView = forwardRef<AtPlaceholderViewHandle, AtPlaceholderViewProps>((_, ref) => {
19
- useImperativeHandle(ref, () => ({
20
- getActivePath: () => null,
21
- confirmActive: () => {},
22
- }), [])
23
-
24
- return (
25
- <div className="at-placeholder-view">
26
- <Icon icon="lucide:globe" width={32} className="at-placeholder-icon" />
27
- <div className="at-placeholder-title">网页</div>
28
- <div className="at-placeholder-desc">功能待实现</div>
29
- <div className="at-placeholder-hint">将支持引用网页内容、URL 等</div>
30
- </div>
31
- )
32
- })
33
-
34
- AtBrowserView.displayName = 'AtBrowserView'
@@ -1,34 +0,0 @@
1
- import { forwardRef, useImperativeHandle } from 'react'
2
- import { Icon } from '@iconify/react'
3
- import './AtViewStyles.css'
4
-
5
- export interface AtPlaceholderViewProps {
6
- query: string
7
- activeIndex: number
8
- onSelect: (path: string) => void
9
- onSetActive: (index: number) => void
10
- onUpdateCount: (count: number) => void
11
- }
12
-
13
- export interface AtPlaceholderViewHandle {
14
- getActivePath: () => string | null
15
- confirmActive: () => void
16
- }
17
-
18
- export const AtChatsView = forwardRef<AtPlaceholderViewHandle, AtPlaceholderViewProps>((_, ref) => {
19
- useImperativeHandle(ref, () => ({
20
- getActivePath: () => null,
21
- confirmActive: () => {},
22
- }), [])
23
-
24
- return (
25
- <div className="at-placeholder-view">
26
- <Icon icon="lucide:message-square" width={32} className="at-placeholder-icon" />
27
- <div className="at-placeholder-title">历史对话</div>
28
- <div className="at-placeholder-desc">功能待实现</div>
29
- <div className="at-placeholder-hint">将支持引用之前的对话记录</div>
30
- </div>
31
- )
32
- })
33
-
34
- AtChatsView.displayName = 'AtChatsView'
@@ -1,34 +0,0 @@
1
- import { forwardRef, useImperativeHandle } from 'react'
2
- import { Icon } from '@iconify/react'
3
- import './AtViewStyles.css'
4
-
5
- export interface AtPlaceholderViewProps {
6
- query: string
7
- activeIndex: number
8
- onSelect: (path: string) => void
9
- onSetActive: (index: number) => void
10
- onUpdateCount: (count: number) => void
11
- }
12
-
13
- export interface AtPlaceholderViewHandle {
14
- getActivePath: () => string | null
15
- confirmActive: () => void
16
- }
17
-
18
- export const AtDocsView = forwardRef<AtPlaceholderViewHandle, AtPlaceholderViewProps>((_, ref) => {
19
- useImperativeHandle(ref, () => ({
20
- getActivePath: () => null,
21
- confirmActive: () => {},
22
- }), [])
23
-
24
- return (
25
- <div className="at-placeholder-view">
26
- <Icon icon="lucide:book-open" width={32} className="at-placeholder-icon" />
27
- <div className="at-placeholder-title">文档</div>
28
- <div className="at-placeholder-desc">功能待实现</div>
29
- <div className="at-placeholder-hint">将支持引用项目文档、API 文档等</div>
30
- </div>
31
- )
32
- })
33
-
34
- AtDocsView.displayName = 'AtDocsView'
@@ -1,168 +0,0 @@
1
- import { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, forwardRef } from 'react'
2
- import { Icon } from '@iconify/react'
3
- import type { ChatAdapter } from '../../../adapter'
4
-
5
- interface FileInfo {
6
- name: string
7
- path: string
8
- isDirectory: boolean
9
- }
10
- import { getFileIcon } from '../../../utils/fileIcon'
11
- import './AtViewStyles.css'
12
-
13
- export interface AtFilesViewProps {
14
- adapter: ChatAdapter
15
- initialDir?: string
16
- query: string
17
- activeIndex: number
18
- onSelect: (path: string) => void
19
- onSetActive: (index: number) => void
20
- onUpdateCount: (count: number) => void
21
- }
22
-
23
- export interface AtFilesViewHandle {
24
- getActivePath: () => string | null
25
- confirmActive: () => void
26
- }
27
-
28
- export const AtFilesView = forwardRef<AtFilesViewHandle, AtFilesViewProps>(({
29
- adapter,
30
- initialDir,
31
- query,
32
- activeIndex,
33
- onSelect,
34
- onSetActive,
35
- onUpdateCount,
36
- }, ref) => {
37
- const [loading, setLoading] = useState(false)
38
- const [currentPath, setCurrentPath] = useState('')
39
- const [entries, setEntries] = useState<FileInfo[]>([])
40
- const initializedRef = useRef(false)
41
-
42
- // 过滤后的文件列表
43
- const filteredEntries = useMemo(() => {
44
- const q = query.trim().toLowerCase()
45
- if (!q) return entries
46
- return entries.filter((f) => f.name.toLowerCase().includes(q))
47
- }, [entries, query])
48
-
49
- // 通知父组件条目数量变化
50
- useEffect(() => {
51
- onUpdateCount(filteredEntries.length)
52
- }, [filteredEntries.length, onUpdateCount])
53
-
54
- // 加载目录
55
- const loadDir = useCallback(async (dir: string) => {
56
- if (!adapter.listDir) return
57
- setLoading(true)
58
- try {
59
- const resolved = (await adapter.resolvePath?.(dir)) || dir
60
- const list = await adapter.listDir(resolved)
61
- const sorted = [...list].sort((a, b) => {
62
- if (a.isDirectory !== b.isDirectory) return a.isDirectory ? -1 : 1
63
- return a.name.localeCompare(b.name)
64
- })
65
- setEntries(sorted)
66
- setCurrentPath(resolved)
67
- onSetActive(-1)
68
- } finally {
69
- setLoading(false)
70
- }
71
- }, [adapter, onSetActive])
72
-
73
- // 返回上级目录
74
- const goUp = useCallback(async () => {
75
- if (!adapter.parentDir) return
76
- const parent = await adapter.parentDir(currentPath)
77
- if (parent && parent !== currentPath) {
78
- await loadDir(parent)
79
- }
80
- }, [adapter, currentPath, loadDir])
81
-
82
- // 返回主目录
83
- const goHome = useCallback(async () => {
84
- if (!adapter.homeDir) return
85
- const home = await adapter.homeDir()
86
- await loadDir(home)
87
- }, [adapter, loadDir])
88
-
89
- // 点击条目
90
- const handleEntryClick = useCallback((f: FileInfo) => {
91
- if (f.isDirectory) {
92
- loadDir(f.path)
93
- return
94
- }
95
- onSelect(f.path)
96
- }, [loadDir, onSelect])
97
-
98
- // 暴露给父组件的方法
99
- useImperativeHandle(ref, () => ({
100
- getActivePath: () => {
101
- if (activeIndex < 0) return null
102
- return filteredEntries[activeIndex]?.path || null
103
- },
104
- confirmActive: () => {
105
- const entry = filteredEntries[activeIndex]
106
- if (entry) {
107
- handleEntryClick(entry)
108
- }
109
- },
110
- }), [activeIndex, filteredEntries, handleEntryClick])
111
-
112
- // 初始加载
113
- useEffect(() => {
114
- if (initializedRef.current) return
115
- initializedRef.current = true
116
-
117
- const init = async () => {
118
- const dir = initialDir || (adapter.homeDir ? await adapter.homeDir() : '')
119
- if (dir) await loadDir(dir)
120
- }
121
- init()
122
- }, [adapter, initialDir, loadDir])
123
-
124
- return (
125
- <div className="at-files-view">
126
- <div className="at-view-section-title">文件和文件夹</div>
127
-
128
- {/* 路径栏 */}
129
- <div className="at-view-pathbar">
130
- <button className="at-view-pathbtn" title="返回上级" onClick={goUp}>
131
- <Icon icon="lucide:arrow-up" width={12} />
132
- </button>
133
- <button className="at-view-pathbtn" title="主目录" onClick={goHome}>
134
- <Icon icon="lucide:home" width={12} />
135
- </button>
136
- <div className="at-view-pathtext" title={currentPath || ''}>
137
- {currentPath || '-'}
138
- </div>
139
- </div>
140
-
141
- {/* 文件列表 */}
142
- <div className="at-view-list">
143
- {loading ? (
144
- <div className="at-view-empty">加载中...</div>
145
- ) : filteredEntries.length === 0 ? (
146
- <div className="at-view-empty">
147
- {query.trim() ? '没有找到匹配项' : '目录为空'}
148
- </div>
149
- ) : (
150
- filteredEntries.map((f, i) => (
151
- <button
152
- key={f.path}
153
- className={`at-view-item${activeIndex === i ? ' active' : ''}`}
154
- onMouseEnter={() => onSetActive(i)}
155
- onClick={() => handleEntryClick(f)}
156
- >
157
- <Icon icon={f.isDirectory ? 'lucide:folder' : getFileIcon(f.name)} width={14} className="at-view-item-icon" />
158
- <span className="at-view-item-name">{f.name}</span>
159
- <span className="at-view-item-path">{f.path}</span>
160
- </button>
161
- ))
162
- )}
163
- </div>
164
- </div>
165
- )
166
- })
167
-
168
- AtFilesView.displayName = 'AtFilesView'
@@ -1,34 +0,0 @@
1
- import { forwardRef, useImperativeHandle } from 'react'
2
- import { Icon } from '@iconify/react'
3
- import './AtViewStyles.css'
4
-
5
- export interface AtPlaceholderViewProps {
6
- query: string
7
- activeIndex: number
8
- onSelect: (path: string) => void
9
- onSetActive: (index: number) => void
10
- onUpdateCount: (count: number) => void
11
- }
12
-
13
- export interface AtPlaceholderViewHandle {
14
- getActivePath: () => string | null
15
- confirmActive: () => void
16
- }
17
-
18
- export const AtTerminalsView = forwardRef<AtPlaceholderViewHandle, AtPlaceholderViewProps>((_, ref) => {
19
- useImperativeHandle(ref, () => ({
20
- getActivePath: () => null,
21
- confirmActive: () => {},
22
- }), [])
23
-
24
- return (
25
- <div className="at-placeholder-view">
26
- <Icon icon="lucide:terminal" width={32} className="at-placeholder-icon" />
27
- <div className="at-placeholder-title">终端</div>
28
- <div className="at-placeholder-desc">功能待实现</div>
29
- <div className="at-placeholder-hint">将支持引用终端输出、命令历史等</div>
30
- </div>
31
- )
32
- })
33
-
34
- AtTerminalsView.displayName = 'AtTerminalsView'
@@ -1,143 +0,0 @@
1
- /* 子视图共享样式 */
2
-
3
- .at-files-view {
4
- display: flex;
5
- flex-direction: column;
6
- }
7
-
8
- .at-view-section-title {
9
- font-size: 11px;
10
- color: var(--chat-text-muted, #888);
11
- padding: 6px 8px 4px;
12
- text-transform: uppercase;
13
- letter-spacing: 0.5px;
14
- }
15
-
16
- .at-view-pathbar {
17
- display: flex;
18
- align-items: center;
19
- gap: 4px;
20
- padding: 4px 8px 8px;
21
- }
22
-
23
- .at-view-pathbtn {
24
- width: 22px;
25
- height: 22px;
26
- border-radius: 4px;
27
- background: transparent;
28
- border: 1px solid var(--chat-border, rgba(255, 255, 255, 0.1));
29
- color: var(--chat-text-muted, #999);
30
- cursor: pointer;
31
- display: flex;
32
- align-items: center;
33
- justify-content: center;
34
- }
35
-
36
- .at-view-pathbtn:hover {
37
- background: var(--chat-muted-hover, rgba(255, 255, 255, 0.06));
38
- color: var(--chat-text, #ccc);
39
- }
40
-
41
- .at-view-pathtext {
42
- flex: 1;
43
- min-width: 0;
44
- font-size: 11px;
45
- color: var(--chat-text-muted, #777);
46
- white-space: nowrap;
47
- overflow: hidden;
48
- text-overflow: ellipsis;
49
- }
50
-
51
- .at-view-list {
52
- display: flex;
53
- flex-direction: column;
54
- gap: 1px;
55
- }
56
-
57
- .at-view-item {
58
- display: flex;
59
- align-items: center;
60
- gap: 8px;
61
- text-align: left;
62
- padding: 7px 10px;
63
- border-radius: 6px;
64
- border: 1px solid transparent;
65
- background: transparent;
66
- cursor: pointer;
67
- color: var(--chat-text, #ccc);
68
- width: 100%;
69
- }
70
-
71
- .at-view-item:hover {
72
- background: var(--chat-muted-hover, rgba(255, 255, 255, 0.06));
73
- }
74
-
75
- .at-view-item.active {
76
- background: rgba(59, 130, 246, 0.15);
77
- border-color: rgba(59, 130, 246, 0.3);
78
- }
79
-
80
- .at-view-item-icon {
81
- color: var(--chat-text-muted, #999);
82
- flex-shrink: 0;
83
- }
84
-
85
- .at-view-item-name {
86
- font-size: 13px;
87
- color: var(--chat-text, #ddd);
88
- flex-shrink: 0;
89
- max-width: 160px;
90
- overflow: hidden;
91
- text-overflow: ellipsis;
92
- white-space: nowrap;
93
- }
94
-
95
- .at-view-item-path {
96
- font-size: 11px;
97
- color: var(--chat-text-muted, #555);
98
- min-width: 0;
99
- overflow: hidden;
100
- text-overflow: ellipsis;
101
- white-space: nowrap;
102
- flex: 1;
103
- }
104
-
105
- .at-view-empty {
106
- padding: 12px 10px;
107
- color: var(--chat-text-muted, #666);
108
- font-size: 12px;
109
- text-align: center;
110
- }
111
-
112
- /* 占位视图样式 */
113
- .at-placeholder-view {
114
- display: flex;
115
- flex-direction: column;
116
- align-items: center;
117
- justify-content: center;
118
- padding: 32px 16px;
119
- text-align: center;
120
- }
121
-
122
- .at-placeholder-icon {
123
- color: var(--chat-text-muted, #555);
124
- margin-bottom: 12px;
125
- }
126
-
127
- .at-placeholder-title {
128
- font-size: 14px;
129
- font-weight: 500;
130
- color: var(--chat-text-muted, #888);
131
- margin-bottom: 8px;
132
- }
133
-
134
- .at-placeholder-desc {
135
- font-size: 13px;
136
- color: var(--chat-text-muted, #666);
137
- margin-bottom: 4px;
138
- }
139
-
140
- .at-placeholder-hint {
141
- font-size: 11px;
142
- color: var(--chat-text-muted, #555);
143
- }
@@ -1,9 +0,0 @@
1
- export { AtFilesView } from './AtFilesView'
2
- export type { AtFilesViewProps, AtFilesViewHandle } from './AtFilesView'
3
-
4
- export { AtDocsView } from './AtDocsView'
5
- export { AtTerminalsView } from './AtTerminalsView'
6
- export { AtChatsView } from './AtChatsView'
7
- export { AtBranchView } from './AtBranchView'
8
- export { AtBrowserView } from './AtBrowserView'
9
- export type { AtPlaceholderViewProps, AtPlaceholderViewHandle } from './AtDocsView'
@@ -1,9 +0,0 @@
1
- /**
2
- * ContentRenderer 样式
3
- */
4
-
5
- .content-renderer {
6
- display: flex;
7
- flex-direction: column;
8
- gap: 4px;
9
- }