@townco/ui 0.1.6 → 0.1.8

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 (255) hide show
  1. package/README.md +11 -11
  2. package/dist/core/hooks/index.d.ts +1 -0
  3. package/dist/core/hooks/index.js +1 -0
  4. package/dist/core/hooks/use-chat-input.d.ts +17 -17
  5. package/dist/core/hooks/use-chat-input.js +55 -64
  6. package/dist/core/hooks/use-chat-messages.d.ts +11 -11
  7. package/dist/core/hooks/use-chat-messages.js +114 -121
  8. package/dist/core/hooks/use-chat-session.d.ts +5 -5
  9. package/dist/core/hooks/use-chat-session.js +80 -78
  10. package/dist/core/hooks/use-media-query.d.ts +5 -5
  11. package/dist/core/hooks/use-media-query.js +42 -38
  12. package/dist/core/index.d.ts +1 -1
  13. package/dist/core/index.js +1 -1
  14. package/dist/core/schemas/chat.d.ts +56 -83
  15. package/dist/core/schemas/chat.js +25 -27
  16. package/dist/core/store/chat-store.d.ts +22 -28
  17. package/dist/core/store/chat-store.js +50 -59
  18. package/dist/gui/components/Button.d.ts +7 -23
  19. package/dist/gui/components/Button.js +27 -40
  20. package/dist/gui/components/Card.d.ts +7 -26
  21. package/dist/gui/components/Card.js +8 -54
  22. package/dist/gui/components/ChatHeader.d.ts +31 -58
  23. package/dist/gui/components/ChatHeader.js +68 -171
  24. package/dist/gui/components/ChatInput.d.ts +54 -58
  25. package/dist/gui/components/ChatInput.js +207 -194
  26. package/dist/gui/components/ChatInputCommandMenu.d.ts +20 -0
  27. package/dist/gui/components/ChatInputCommandMenu.js +62 -0
  28. package/dist/gui/components/ChatLayout.d.ts +41 -71
  29. package/dist/gui/components/ChatLayout.js +87 -214
  30. package/dist/gui/components/ChatPanelTabContent.d.ts +9 -18
  31. package/dist/gui/components/ChatPanelTabContent.js +10 -88
  32. package/dist/gui/components/ChatSecondaryPanel.d.ts +11 -14
  33. package/dist/gui/components/ChatSecondaryPanel.js +38 -115
  34. package/dist/gui/components/ChatSidebar.d.ts +13 -26
  35. package/dist/gui/components/ChatSidebar.js +14 -48
  36. package/dist/gui/components/ChatStatus.d.ts +2 -4
  37. package/dist/gui/components/ChatStatus.js +34 -45
  38. package/dist/gui/components/Conversation.d.ts +14 -17
  39. package/dist/gui/components/Conversation.js +83 -143
  40. package/dist/gui/components/Dialog.d.ts +11 -57
  41. package/dist/gui/components/Dialog.js +8 -84
  42. package/dist/gui/components/DropdownMenu.d.ts +20 -101
  43. package/dist/gui/components/DropdownMenu.js +14 -161
  44. package/dist/gui/components/HeightTransition.d.ts +7 -12
  45. package/dist/gui/components/HeightTransition.js +77 -88
  46. package/dist/gui/components/Input.d.ts +6 -13
  47. package/dist/gui/components/Input.js +16 -27
  48. package/dist/gui/components/Label.d.ts +1 -7
  49. package/dist/gui/components/Label.js +2 -12
  50. package/dist/gui/components/MarkdownRenderer.d.ts +4 -6
  51. package/dist/gui/components/MarkdownRenderer.js +81 -178
  52. package/dist/gui/components/Message.d.ts +22 -25
  53. package/dist/gui/components/Message.js +97 -44
  54. package/dist/gui/components/MessageContent.d.ts +22 -29
  55. package/dist/gui/components/MessageContent.js +85 -157
  56. package/dist/gui/components/Reasoning.d.ts +24 -30
  57. package/dist/gui/components/Reasoning.js +60 -187
  58. package/dist/gui/components/Response.d.ts +9 -11
  59. package/dist/gui/components/Response.js +90 -229
  60. package/dist/gui/components/Select.d.ts +10 -69
  61. package/dist/gui/components/Select.js +12 -118
  62. package/dist/gui/components/Sonner.d.ts +1 -3
  63. package/dist/gui/components/Sonner.js +18 -29
  64. package/dist/gui/components/Tabs.d.ts +4 -24
  65. package/dist/gui/components/Tabs.js +4 -32
  66. package/dist/gui/components/Task.d.ts +24 -28
  67. package/dist/gui/components/Task.js +31 -164
  68. package/dist/gui/components/Textarea.d.ts +7 -15
  69. package/dist/gui/components/Textarea.js +46 -63
  70. package/dist/gui/components/ThinkingBlock.d.ts +10 -20
  71. package/dist/gui/components/ThinkingBlock.js +35 -134
  72. package/dist/gui/components/TodoList.d.ts +10 -12
  73. package/dist/gui/components/TodoList.js +7 -22
  74. package/dist/gui/components/TodoListItem.d.ts +6 -9
  75. package/dist/gui/components/TodoListItem.js +4 -18
  76. package/dist/gui/components/index.d.ts +16 -59
  77. package/dist/gui/components/index.js +18 -42
  78. package/dist/gui/lib/utils.js +1 -1
  79. package/dist/index.d.ts +1 -1
  80. package/dist/index.js +1 -1
  81. package/dist/index.test.js +1 -0
  82. package/dist/sdk/client/acp-client.d.ts +76 -88
  83. package/dist/sdk/client/acp-client.js +217 -215
  84. package/dist/sdk/index.d.ts +1 -1
  85. package/dist/sdk/index.js +1 -1
  86. package/dist/sdk/schemas/agent.d.ts +64 -111
  87. package/dist/sdk/schemas/agent.js +24 -24
  88. package/dist/sdk/schemas/message.d.ts +147 -245
  89. package/dist/sdk/schemas/message.js +40 -40
  90. package/dist/sdk/schemas/session.d.ts +135 -219
  91. package/dist/sdk/schemas/session.js +27 -27
  92. package/dist/sdk/transports/http.d.ts +55 -55
  93. package/dist/sdk/transports/http.js +469 -472
  94. package/dist/sdk/transports/stdio.d.ts +20 -20
  95. package/dist/sdk/transports/stdio.js +286 -289
  96. package/dist/sdk/transports/types.d.ts +42 -42
  97. package/dist/sdk/transports/websocket.d.ts +12 -12
  98. package/dist/sdk/transports/websocket.js +46 -52
  99. package/dist/tui/components/ChatView.d.ts +2 -4
  100. package/dist/tui/components/ChatView.js +18 -51
  101. package/dist/tui/components/GameOfLife.js +35 -64
  102. package/dist/tui/components/InputBox.d.ts +11 -18
  103. package/dist/tui/components/InputBox.js +10 -70
  104. package/dist/tui/components/MessageList.d.ts +2 -4
  105. package/dist/tui/components/MessageList.js +10 -37
  106. package/dist/tui/components/MultiSelect.d.ts +10 -15
  107. package/dist/tui/components/MultiSelect.js +73 -116
  108. package/dist/tui/components/ReadlineInput.d.ts +6 -12
  109. package/dist/tui/components/ReadlineInput.js +237 -252
  110. package/dist/tui/components/SingleSelect.d.ts +9 -15
  111. package/dist/tui/components/SingleSelect.js +43 -84
  112. package/dist/tui/components/StatusBar.d.ts +6 -11
  113. package/dist/tui/components/StatusBar.js +67 -102
  114. package/dist/tui/index.d.ts +1 -1
  115. package/dist/tui/index.js +1 -1
  116. package/package.json +6 -4
  117. package/src/styles/global.css +2 -0
  118. package/dist/core/hooks/index.d.ts.map +0 -1
  119. package/dist/core/hooks/index.js.map +0 -1
  120. package/dist/core/hooks/use-chat-input.d.ts.map +0 -1
  121. package/dist/core/hooks/use-chat-input.js.map +0 -1
  122. package/dist/core/hooks/use-chat-messages.d.ts.map +0 -1
  123. package/dist/core/hooks/use-chat-messages.js.map +0 -1
  124. package/dist/core/hooks/use-chat-session.d.ts.map +0 -1
  125. package/dist/core/hooks/use-chat-session.js.map +0 -1
  126. package/dist/core/index.d.ts.map +0 -1
  127. package/dist/core/index.js.map +0 -1
  128. package/dist/core/schemas/chat.d.ts.map +0 -1
  129. package/dist/core/schemas/chat.js.map +0 -1
  130. package/dist/core/schemas/index.d.ts.map +0 -1
  131. package/dist/core/schemas/index.js.map +0 -1
  132. package/dist/core/store/chat-store.d.ts.map +0 -1
  133. package/dist/core/store/chat-store.js.map +0 -1
  134. package/dist/gui/components/Button.d.ts.map +0 -1
  135. package/dist/gui/components/Button.js.map +0 -1
  136. package/dist/gui/components/Card.d.ts.map +0 -1
  137. package/dist/gui/components/Card.js.map +0 -1
  138. package/dist/gui/components/ChatInput.d.ts.map +0 -1
  139. package/dist/gui/components/ChatInput.js.map +0 -1
  140. package/dist/gui/components/ChatInterface.d.ts +0 -12
  141. package/dist/gui/components/ChatInterface.d.ts.map +0 -1
  142. package/dist/gui/components/ChatInterface.js +0 -204
  143. package/dist/gui/components/ChatInterface.js.map +0 -1
  144. package/dist/gui/components/ChatPreview.d.ts +0 -12
  145. package/dist/gui/components/ChatPreview.d.ts.map +0 -1
  146. package/dist/gui/components/ChatPreview.js +0 -214
  147. package/dist/gui/components/ChatPreview.js.map +0 -1
  148. package/dist/gui/components/ChatSecondaryPanel.d.ts.map +0 -1
  149. package/dist/gui/components/ChatSecondaryPanel.js.map +0 -1
  150. package/dist/gui/components/ChatStatus.d.ts.map +0 -1
  151. package/dist/gui/components/ChatStatus.js.map +0 -1
  152. package/dist/gui/components/ChatView.d.ts +0 -8
  153. package/dist/gui/components/ChatView.d.ts.map +0 -1
  154. package/dist/gui/components/ChatView.js +0 -42
  155. package/dist/gui/components/ChatView.js.map +0 -1
  156. package/dist/gui/components/ConfigPanel.d.ts +0 -20
  157. package/dist/gui/components/ConfigPanel.d.ts.map +0 -1
  158. package/dist/gui/components/ConfigPanel.js +0 -225
  159. package/dist/gui/components/ConfigPanel.js.map +0 -1
  160. package/dist/gui/components/Conversation.d.ts.map +0 -1
  161. package/dist/gui/components/Conversation.js.map +0 -1
  162. package/dist/gui/components/Dialog.d.ts.map +0 -1
  163. package/dist/gui/components/Dialog.js.map +0 -1
  164. package/dist/gui/components/HeightTransition.d.ts.map +0 -1
  165. package/dist/gui/components/HeightTransition.js.map +0 -1
  166. package/dist/gui/components/Input.d.ts.map +0 -1
  167. package/dist/gui/components/Input.js.map +0 -1
  168. package/dist/gui/components/InputBox.d.ts +0 -21
  169. package/dist/gui/components/InputBox.d.ts.map +0 -1
  170. package/dist/gui/components/InputBox.js +0 -90
  171. package/dist/gui/components/InputBox.js.map +0 -1
  172. package/dist/gui/components/Label.d.ts.map +0 -1
  173. package/dist/gui/components/Label.js.map +0 -1
  174. package/dist/gui/components/MarkdownRenderer.d.ts.map +0 -1
  175. package/dist/gui/components/MarkdownRenderer.js.map +0 -1
  176. package/dist/gui/components/Message.d.ts.map +0 -1
  177. package/dist/gui/components/Message.js.map +0 -1
  178. package/dist/gui/components/MessageContent.d.ts.map +0 -1
  179. package/dist/gui/components/MessageContent.js.map +0 -1
  180. package/dist/gui/components/MessageList.d.ts.map +0 -1
  181. package/dist/gui/components/MessageList.js.map +0 -1
  182. package/dist/gui/components/PlaygroundLayout.d.ts +0 -14
  183. package/dist/gui/components/PlaygroundLayout.d.ts.map +0 -1
  184. package/dist/gui/components/PlaygroundLayout.js +0 -49
  185. package/dist/gui/components/PlaygroundLayout.js.map +0 -1
  186. package/dist/gui/components/Reasoning.d.ts.map +0 -1
  187. package/dist/gui/components/Reasoning.js.map +0 -1
  188. package/dist/gui/components/Response.d.ts.map +0 -1
  189. package/dist/gui/components/Response.js.map +0 -1
  190. package/dist/gui/components/Select.d.ts.map +0 -1
  191. package/dist/gui/components/Select.js.map +0 -1
  192. package/dist/gui/components/StatusBar.d.ts +0 -12
  193. package/dist/gui/components/StatusBar.d.ts.map +0 -1
  194. package/dist/gui/components/StatusBar.js +0 -58
  195. package/dist/gui/components/StatusBar.js.map +0 -1
  196. package/dist/gui/components/Tabs.d.ts.map +0 -1
  197. package/dist/gui/components/Tabs.js.map +0 -1
  198. package/dist/gui/components/Task.d.ts.map +0 -1
  199. package/dist/gui/components/Task.js.map +0 -1
  200. package/dist/gui/components/Textarea.d.ts.map +0 -1
  201. package/dist/gui/components/Textarea.js.map +0 -1
  202. package/dist/gui/components/ThinkingBlock.d.ts.map +0 -1
  203. package/dist/gui/components/ThinkingBlock.js.map +0 -1
  204. package/dist/gui/components/TodoList.d.ts.map +0 -1
  205. package/dist/gui/components/TodoList.js.map +0 -1
  206. package/dist/gui/components/TodoListItem.d.ts.map +0 -1
  207. package/dist/gui/components/TodoListItem.js.map +0 -1
  208. package/dist/gui/components/index.d.ts.map +0 -1
  209. package/dist/gui/components/index.js.map +0 -1
  210. package/dist/gui/index.d.ts.map +0 -1
  211. package/dist/gui/index.js.map +0 -1
  212. package/dist/gui/lib/utils.d.ts.map +0 -1
  213. package/dist/gui/lib/utils.js.map +0 -1
  214. package/dist/index.d.ts.map +0 -1
  215. package/dist/index.js.map +0 -1
  216. package/dist/sdk/client/acp-client.d.ts.map +0 -1
  217. package/dist/sdk/client/acp-client.js.map +0 -1
  218. package/dist/sdk/client/index.d.ts.map +0 -1
  219. package/dist/sdk/client/index.js.map +0 -1
  220. package/dist/sdk/index.d.ts.map +0 -1
  221. package/dist/sdk/index.js.map +0 -1
  222. package/dist/sdk/schemas/agent.d.ts.map +0 -1
  223. package/dist/sdk/schemas/agent.js.map +0 -1
  224. package/dist/sdk/schemas/index.d.ts.map +0 -1
  225. package/dist/sdk/schemas/index.js.map +0 -1
  226. package/dist/sdk/schemas/message.d.ts.map +0 -1
  227. package/dist/sdk/schemas/message.js.map +0 -1
  228. package/dist/sdk/schemas/session.d.ts.map +0 -1
  229. package/dist/sdk/schemas/session.js.map +0 -1
  230. package/dist/sdk/transports/http.d.ts.map +0 -1
  231. package/dist/sdk/transports/http.js.map +0 -1
  232. package/dist/sdk/transports/index.d.ts.map +0 -1
  233. package/dist/sdk/transports/index.js.map +0 -1
  234. package/dist/sdk/transports/stdio.d.ts.map +0 -1
  235. package/dist/sdk/transports/stdio.js.map +0 -1
  236. package/dist/sdk/transports/types.d.ts.map +0 -1
  237. package/dist/sdk/transports/types.js.map +0 -1
  238. package/dist/sdk/transports/websocket.d.ts.map +0 -1
  239. package/dist/sdk/transports/websocket.js.map +0 -1
  240. package/dist/tui/components/ChatView.d.ts.map +0 -1
  241. package/dist/tui/components/ChatView.js.map +0 -1
  242. package/dist/tui/components/GameOfLife.d.ts.map +0 -1
  243. package/dist/tui/components/GameOfLife.js.map +0 -1
  244. package/dist/tui/components/InputBox.d.ts.map +0 -1
  245. package/dist/tui/components/InputBox.js.map +0 -1
  246. package/dist/tui/components/MessageList.d.ts.map +0 -1
  247. package/dist/tui/components/MessageList.js.map +0 -1
  248. package/dist/tui/components/ReadlineInput.d.ts.map +0 -1
  249. package/dist/tui/components/ReadlineInput.js.map +0 -1
  250. package/dist/tui/components/StatusBar.d.ts.map +0 -1
  251. package/dist/tui/components/StatusBar.js.map +0 -1
  252. package/dist/tui/components/index.d.ts.map +0 -1
  253. package/dist/tui/components/index.js.map +0 -1
  254. package/dist/tui/index.d.ts.map +0 -1
  255. package/dist/tui/index.js.map +0 -1
@@ -1,232 +1,105 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
2
  import { ArrowDown } from "lucide-react";
2
3
  import * as React from "react";
3
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
4
  import { cn } from "../lib/utils.js";
5
5
  import { Toaster } from "./Sonner.js";
6
-
7
6
  const ChatLayoutContext = React.createContext(undefined);
8
7
  const useChatLayoutContext = () => {
9
- const context = React.useContext(ChatLayoutContext);
10
- if (!context) {
11
- throw new Error(
12
- "ChatLayout components must be used within ChatLayout.Root",
13
- );
14
- }
15
- return context;
8
+ const context = React.useContext(ChatLayoutContext);
9
+ if (!context) {
10
+ throw new Error("ChatLayout components must be used within ChatLayout.Root");
11
+ }
12
+ return context;
16
13
  };
17
- const ChatLayoutRoot = React.forwardRef(
18
- (
19
- {
20
- defaultSidebarOpen = false,
21
- defaultPanelSize = "hidden",
22
- defaultActiveTab = "todo",
23
- className,
24
- children,
25
- ...props
26
- },
27
- ref,
28
- ) => {
29
- const [sidebarOpen, setSidebarOpen] = React.useState(defaultSidebarOpen);
30
- const [panelSize, setPanelSize] = React.useState(defaultPanelSize);
31
- const [activeTab, setActiveTab] = React.useState(defaultActiveTab);
32
- return _jsx(ChatLayoutContext.Provider, {
33
- value: {
34
- sidebarOpen,
35
- setSidebarOpen,
36
- panelSize,
37
- setPanelSize,
38
- activeTab,
39
- setActiveTab,
40
- },
41
- children: _jsx("div", {
42
- ref: ref,
43
- className: cn(
44
- "flex h-screen flex-row bg-background text-foreground",
45
- className,
46
- ),
47
- ...props,
48
- children: children,
49
- }),
50
- });
51
- },
52
- );
14
+ const ChatLayoutRoot = React.forwardRef(({ defaultSidebarOpen = false, defaultPanelSize = "hidden", defaultActiveTab = "todo", className, children, ...props }, ref) => {
15
+ const [sidebarOpen, setSidebarOpen] = React.useState(defaultSidebarOpen);
16
+ const [panelSize, setPanelSize] = React.useState(defaultPanelSize);
17
+ const [activeTab, setActiveTab] = React.useState(defaultActiveTab);
18
+ return (_jsx(ChatLayoutContext.Provider, { value: {
19
+ sidebarOpen,
20
+ setSidebarOpen,
21
+ panelSize,
22
+ setPanelSize,
23
+ activeTab,
24
+ setActiveTab,
25
+ }, children: _jsx("div", { ref: ref, className: cn("flex h-screen flex-row bg-background text-foreground", className), ...props, children: children }) }));
26
+ });
53
27
  ChatLayoutRoot.displayName = "ChatLayout.Root";
54
- const ChatLayoutHeader = React.forwardRef(
55
- ({ className, children, ...props }, ref) => {
56
- return _jsx("div", {
57
- ref: ref,
58
- className: cn(
59
- "relative z-10 border-b border-border bg-card shrink-0",
60
- className,
61
- ),
62
- ...props,
63
- children: children,
64
- });
65
- },
66
- );
28
+ const ChatLayoutHeader = React.forwardRef(({ className, children, ...props }, ref) => {
29
+ return (_jsx("div", { ref: ref, className: cn("relative z-10 border-b border-border bg-card shrink-0", className), ...props, children: children }));
30
+ });
67
31
  ChatLayoutHeader.displayName = "ChatLayout.Header";
68
- const ChatLayoutMain = React.forwardRef(
69
- ({ className, children, ...props }, ref) => {
70
- return _jsx("div", {
71
- ref: ref,
72
- className: cn("flex flex-1 flex-col overflow-hidden", className),
73
- ...props,
74
- children: children,
75
- });
76
- },
77
- );
32
+ const ChatLayoutMain = React.forwardRef(({ className, children, ...props }, ref) => {
33
+ return (_jsx("div", { ref: ref, className: cn("flex flex-1 flex-col overflow-hidden", className), ...props, children: children }));
34
+ });
78
35
  ChatLayoutMain.displayName = "ChatLayout.Main";
79
- const ChatLayoutBody = React.forwardRef(
80
- ({ showToaster = true, className, children, ...props }, ref) => {
81
- return _jsxs("div", {
82
- ref: ref,
83
- className: cn("relative flex flex-1 flex-col overflow-hidden", className),
84
- ...props,
85
- children: [children, showToaster && _jsx(Toaster, {})],
86
- });
87
- },
88
- );
36
+ const ChatLayoutBody = React.forwardRef(({ showToaster = true, className, children, ...props }, ref) => {
37
+ return (_jsxs("div", { ref: ref, className: cn("relative flex flex-1 flex-col overflow-hidden", className), ...props, children: [children, showToaster && _jsx(Toaster, {})] }));
38
+ });
89
39
  ChatLayoutBody.displayName = "ChatLayout.Body";
90
- const ChatLayoutMessages = React.forwardRef(
91
- (
92
- {
93
- className,
94
- children,
95
- onScrollChange,
96
- showScrollToBottom = true,
97
- ...props
98
- },
99
- ref,
100
- ) => {
101
- const [showScrollButton, setShowScrollButton] = React.useState(false);
102
- const scrollContainerRef = React.useRef(null);
103
- // Merge refs
104
- React.useImperativeHandle(ref, () => scrollContainerRef.current);
105
- // Check if user is at bottom of scroll
106
- const checkScrollPosition = React.useCallback(() => {
107
- const container = scrollContainerRef.current;
108
- if (!container) return;
109
- const { scrollTop, scrollHeight, clientHeight } = container;
110
- const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
111
- const isAtBottom = distanceFromBottom < 100; // 100px threshold
112
- setShowScrollButton(!isAtBottom && showScrollToBottom);
113
- onScrollChange?.(isAtBottom);
114
- }, [onScrollChange, showScrollToBottom]);
115
- // Handle scroll events
116
- const handleScroll = React.useCallback(() => {
117
- checkScrollPosition();
118
- }, [checkScrollPosition]);
119
- // Scroll to bottom function
120
- const scrollToBottom = React.useCallback(() => {
121
- const container = scrollContainerRef.current;
122
- if (!container) return;
123
- container.scrollTo({
124
- top: container.scrollHeight,
125
- behavior: "smooth",
126
- });
127
- }, []);
128
- // Check scroll position on mount and when children change
129
- React.useEffect(() => {
130
- checkScrollPosition();
131
- }, [checkScrollPosition]);
132
- return _jsxs("div", {
133
- className: "relative flex-1 overflow-hidden",
134
- children: [
135
- _jsx("div", {
136
- ref: scrollContainerRef,
137
- className: cn("h-full overflow-y-auto", className),
138
- onScroll: handleScroll,
139
- ...props,
140
- children: children,
141
- }),
142
- showScrollButton &&
143
- _jsx("button", {
144
- type: "button",
145
- onClick: scrollToBottom,
146
- className: cn(
147
- "absolute bottom-4 left-1/2 -translate-x-1/2 z-10",
148
- "flex items-center justify-center p-2 rounded-full",
149
- "bg-card border border-border shadow-lg",
150
- "text-foreground",
151
- "hover:bg-accent hover:text-accent-foreground",
152
- "transition-all duration-200 ease-in-out",
153
- "animate-in fade-in slide-in-from-bottom-2",
154
- ),
155
- "aria-label": "Scroll to bottom",
156
- children: _jsx(ArrowDown, { className: "h-4 w-4" }),
157
- }),
158
- ],
159
- });
160
- },
161
- );
40
+ const ChatLayoutMessages = React.forwardRef(({ className, children, onScrollChange, showScrollToBottom = true, ...props }, ref) => {
41
+ const [showScrollButton, setShowScrollButton] = React.useState(false);
42
+ const scrollContainerRef = React.useRef(null);
43
+ // Merge refs
44
+ React.useImperativeHandle(ref, () => scrollContainerRef.current);
45
+ // Check if user is at bottom of scroll
46
+ const checkScrollPosition = React.useCallback(() => {
47
+ const container = scrollContainerRef.current;
48
+ if (!container)
49
+ return;
50
+ const { scrollTop, scrollHeight, clientHeight } = container;
51
+ const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
52
+ const isAtBottom = distanceFromBottom < 100; // 100px threshold
53
+ setShowScrollButton(!isAtBottom && showScrollToBottom);
54
+ onScrollChange?.(isAtBottom);
55
+ }, [onScrollChange, showScrollToBottom]);
56
+ // Handle scroll events
57
+ const handleScroll = React.useCallback(() => {
58
+ checkScrollPosition();
59
+ }, [checkScrollPosition]);
60
+ // Scroll to bottom function
61
+ const scrollToBottom = React.useCallback(() => {
62
+ const container = scrollContainerRef.current;
63
+ if (!container)
64
+ return;
65
+ container.scrollTo({
66
+ top: container.scrollHeight,
67
+ behavior: "smooth",
68
+ });
69
+ }, []);
70
+ // Check scroll position on mount and when children change
71
+ React.useEffect(() => {
72
+ checkScrollPosition();
73
+ }, [checkScrollPosition]);
74
+ return (_jsxs("div", { className: "relative flex-1 overflow-hidden", children: [_jsx("div", { ref: scrollContainerRef, className: cn("h-full overflow-y-auto", className), onScroll: handleScroll, ...props, children: children }), showScrollButton && (_jsx("button", { type: "button", onClick: scrollToBottom, className: cn("absolute bottom-4 left-1/2 -translate-x-1/2 z-10", "flex items-center justify-center p-2 rounded-full", "bg-card border border-border shadow-lg", "text-foreground", "hover:bg-accent hover:text-accent-foreground", "transition-all duration-200 ease-in-out", "animate-in fade-in slide-in-from-bottom-2"), "aria-label": "Scroll to bottom", children: _jsx(ArrowDown, { className: "h-4 w-4" }) }))] }));
75
+ });
162
76
  ChatLayoutMessages.displayName = "ChatLayout.Messages";
163
- const ChatLayoutFooter = React.forwardRef(
164
- ({ className, children, ...props }, ref) => {
165
- return _jsx("div", {
166
- ref: ref,
167
- className: cn(
168
- "bg-linear-to-t from-background to-transparent px-4 pb-4",
169
- className,
170
- ),
171
- ...props,
172
- children: children,
173
- });
174
- },
175
- );
77
+ const ChatLayoutFooter = React.forwardRef(({ className, children, ...props }, ref) => {
78
+ return (_jsx("div", { ref: ref, className: cn("bg-linear-to-t from-background to-transparent px-4 pb-4", className), ...props, children: children }));
79
+ });
176
80
  ChatLayoutFooter.displayName = "ChatLayout.Footer";
177
- const ChatLayoutSidebar = React.forwardRef(
178
- ({ className, children, ...props }, ref) => {
179
- const { sidebarOpen } = useChatLayoutContext();
180
- if (!sidebarOpen) return null;
181
- return _jsx("div", {
182
- ref: ref,
183
- className: cn(
184
- "border-r border-border bg-card w-64 overflow-y-auto",
185
- className,
186
- ),
187
- ...props,
188
- children: children,
189
- });
190
- },
191
- );
81
+ const ChatLayoutSidebar = React.forwardRef(({ className, children, ...props }, ref) => {
82
+ const { sidebarOpen } = useChatLayoutContext();
83
+ if (!sidebarOpen)
84
+ return null;
85
+ return (_jsx("div", { ref: ref, className: cn("border-r border-border bg-card w-64 overflow-y-auto", className), ...props, children: children }));
86
+ });
192
87
  ChatLayoutSidebar.displayName = "ChatLayout.Sidebar";
193
- const ChatLayoutAside = React.forwardRef(
194
- ({ breakpoint = "lg", className, children, ...props }, ref) => {
195
- const { panelSize } = useChatLayoutContext();
196
- // Hidden state - don't render
197
- if (panelSize === "hidden") return null;
198
- return _jsx("div", {
199
- ref: ref,
200
- className: cn(
201
- // Hidden by default, visible at breakpoint
202
- "hidden border-l border-border bg-card overflow-y-auto transition-all duration-300",
203
- // Breakpoint visibility
204
- breakpoint === "md" && "md:block",
205
- breakpoint === "lg" && "lg:block",
206
- breakpoint === "xl" && "xl:block",
207
- breakpoint === "2xl" && "2xl:block",
208
- // Size variants
209
- panelSize === "small" && "w-80",
210
- panelSize === "large" && "w-[32rem]",
211
- className,
212
- ),
213
- ...props,
214
- children: children,
215
- });
216
- },
217
- );
88
+ const ChatLayoutAside = React.forwardRef(({ breakpoint = "lg", className, children, ...props }, ref) => {
89
+ const { panelSize } = useChatLayoutContext();
90
+ // Hidden state - don't render
91
+ if (panelSize === "hidden")
92
+ return null;
93
+ return (_jsx("div", { ref: ref, className: cn(
94
+ // Hidden by default, visible at breakpoint
95
+ "hidden border-l border-border bg-card overflow-y-auto transition-all duration-300",
96
+ // Breakpoint visibility
97
+ breakpoint === "md" && "md:block", breakpoint === "lg" && "lg:block", breakpoint === "xl" && "xl:block", breakpoint === "2xl" && "2xl:block",
98
+ // Size variants
99
+ panelSize === "small" && "w-80", panelSize === "large" && "w-lg", className), ...props, children: children }));
100
+ });
218
101
  ChatLayoutAside.displayName = "ChatLayout.Aside";
219
102
  /* -------------------------------------------------------------------------------------------------
220
103
  * Exports
221
104
  * -----------------------------------------------------------------------------------------------*/
222
- export {
223
- ChatLayoutRoot as Root,
224
- ChatLayoutHeader as Header,
225
- ChatLayoutMain as Main,
226
- ChatLayoutBody as Body,
227
- ChatLayoutMessages as Messages,
228
- ChatLayoutFooter as Footer,
229
- ChatLayoutSidebar as Sidebar,
230
- ChatLayoutAside as Aside,
231
- useChatLayoutContext,
232
- };
105
+ export { ChatLayoutRoot as Root, ChatLayoutHeader as Header, ChatLayoutMain as Main, ChatLayoutBody as Body, ChatLayoutMessages as Messages, ChatLayoutFooter as Footer, ChatLayoutSidebar as Sidebar, ChatLayoutAside as Aside, useChatLayoutContext, };
@@ -4,24 +4,15 @@ import type { TodoItem } from "./TodoListItem.js";
4
4
  * Shared tab content components for both mobile (ChatHeader) and desktop (Panel) views
5
5
  * Following component architecture best practices
6
6
  */
7
- export interface TodoTabContentProps
8
- extends React.HTMLAttributes<HTMLDivElement> {
9
- todos: TodoItem[];
7
+ export interface TodoTabContentProps extends React.HTMLAttributes<HTMLDivElement> {
8
+ todos: TodoItem[];
10
9
  }
11
- export declare const TodoTabContent: React.ForwardRefExoticComponent<
12
- TodoTabContentProps & React.RefAttributes<HTMLDivElement>
13
- >;
14
- export interface FilesTabContentProps
15
- extends React.HTMLAttributes<HTMLDivElement> {
16
- files?: string[];
10
+ export declare const TodoTabContent: React.ForwardRefExoticComponent<TodoTabContentProps & React.RefAttributes<HTMLDivElement>>;
11
+ export interface FilesTabContentProps extends React.HTMLAttributes<HTMLDivElement> {
12
+ files?: string[];
17
13
  }
18
- export declare const FilesTabContent: React.ForwardRefExoticComponent<
19
- FilesTabContentProps & React.RefAttributes<HTMLDivElement>
20
- >;
21
- export interface DatabaseTabContentProps
22
- extends React.HTMLAttributes<HTMLDivElement> {
23
- data?: unknown;
14
+ export declare const FilesTabContent: React.ForwardRefExoticComponent<FilesTabContentProps & React.RefAttributes<HTMLDivElement>>;
15
+ export interface DatabaseTabContentProps extends React.HTMLAttributes<HTMLDivElement> {
16
+ data?: unknown;
24
17
  }
25
- export declare const DatabaseTabContent: React.ForwardRefExoticComponent<
26
- DatabaseTabContentProps & React.RefAttributes<HTMLDivElement>
27
- >;
18
+ export declare const DatabaseTabContent: React.ForwardRefExoticComponent<DatabaseTabContentProps & React.RefAttributes<HTMLDivElement>>;
@@ -1,93 +1,15 @@
1
- import * as React from "react";
2
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
3
  import { cn } from "../lib/utils.js";
4
- export const TodoTabContent = React.forwardRef(
5
- ({ todos, className, ...props }, ref) => {
6
- return _jsxs("div", {
7
- ref: ref,
8
- className: cn("space-y-4", className),
9
- ...props,
10
- children: [
11
- _jsx("h3", { className: "font-semibold text-lg", children: "Tasks" }),
12
- _jsx("div", {
13
- className: "space-y-2",
14
- children:
15
- todos.length === 0
16
- ? _jsx("p", {
17
- className: "text-sm text-muted-foreground",
18
- children: "No tasks yet",
19
- })
20
- : todos.map((todo) =>
21
- _jsx(
22
- "div",
23
- { className: "text-sm", children: todo.text },
24
- todo.id,
25
- ),
26
- ),
27
- }),
28
- ],
29
- });
30
- },
31
- );
4
+ export const TodoTabContent = React.forwardRef(({ todos, className, ...props }, ref) => {
5
+ return (_jsx("div", { ref: ref, className: cn("space-y-2", className), ...props, children: todos.length === 0 ? (_jsx("div", { className: "flex items-center justify-center h-full min-h-[200px]", children: _jsx("p", { className: "text-sm text-muted-foreground", children: "No todos yet" }) })) : (todos.map((todo) => (_jsx("div", { className: "text-sm", children: todo.text }, todo.id)))) }));
6
+ });
32
7
  TodoTabContent.displayName = "TodoTabContent";
33
- export const FilesTabContent = React.forwardRef(
34
- ({ files = [], className, ...props }, ref) => {
35
- return _jsxs("div", {
36
- ref: ref,
37
- className: cn("space-y-4", className),
38
- ...props,
39
- children: [
40
- _jsx("h3", { className: "font-semibold text-lg", children: "Files" }),
41
- files.length === 0
42
- ? _jsx("p", {
43
- className: "text-sm text-muted-foreground",
44
- children: "No files attached",
45
- })
46
- : _jsx("div", {
47
- className: "space-y-2",
48
- children: files.map((file) =>
49
- _jsx("div", { className: "text-sm", children: file }, file),
50
- ),
51
- }),
52
- ],
53
- });
54
- },
55
- );
8
+ export const FilesTabContent = React.forwardRef(({ files = [], className, ...props }, ref) => {
9
+ return (_jsx("div", { ref: ref, className: cn("space-y-2", className), ...props, children: files.length === 0 ? (_jsx("div", { className: "flex items-center justify-center h-full min-h-[200px]", children: _jsx("p", { className: "text-sm text-muted-foreground", children: "No files attached" }) })) : (files.map((file) => (_jsx("div", { className: "text-sm", children: file }, file)))) }));
10
+ });
56
11
  FilesTabContent.displayName = "FilesTabContent";
57
- export const DatabaseTabContent = React.forwardRef(
58
- ({ data, className, ...props }, ref) => {
59
- return _jsxs("div", {
60
- ref: ref,
61
- className: cn("space-y-4", className),
62
- ...props,
63
- children: [
64
- _jsx("h3", {
65
- className: "font-semibold text-lg",
66
- children: "Database",
67
- }),
68
- _jsxs("div", {
69
- className: "text-sm text-muted-foreground",
70
- children: [
71
- _jsx("p", {
72
- children:
73
- "Database viewer - panel automatically expanded to large size",
74
- }),
75
- _jsxs("div", {
76
- className: "mt-4 p-4 border border-border rounded",
77
- children: [
78
- _jsx("p", { children: "Your large data table would go here" }),
79
- data && typeof data === "object"
80
- ? _jsx("pre", {
81
- className: "mt-2 text-xs overflow-auto",
82
- children: JSON.stringify(data, null, 2),
83
- })
84
- : null,
85
- ],
86
- }),
87
- ],
88
- }),
89
- ],
90
- });
91
- },
92
- );
12
+ export const DatabaseTabContent = React.forwardRef(({ data, className, ...props }, ref) => {
13
+ return (_jsxs("div", { ref: ref, className: cn("space-y-4", className), ...props, children: [_jsx("h3", { className: "font-semibold text-lg", children: "Database" }), _jsxs("div", { className: "text-sm text-muted-foreground", children: [_jsx("p", { children: "Database viewer - panel automatically expanded to large size" }), _jsxs("div", { className: "mt-4 p-4 border border-border rounded", children: [_jsx("p", { children: "Your large data table would go here" }), data && typeof data === "object" ? (_jsx("pre", { className: "mt-2 text-xs overflow-auto", children: JSON.stringify(data, null, 2) })) : null] })] })] }));
14
+ });
93
15
  DatabaseTabContent.displayName = "DatabaseTabContent";
@@ -6,18 +6,15 @@ import type { TodoItem } from "./TodoListItem.js";
6
6
  * 1. Hook-based: Pass `client` prop (future support when todos are in store)
7
7
  * 2. Prop-based: Pass `todos` prop directly
8
8
  */
9
- export interface ChatSecondaryPanelProps
10
- extends React.HTMLAttributes<HTMLDivElement> {
11
- /**
12
- * ACP Client for hook-based todo fetching (future support)
13
- */
14
- client?: AcpClient | null;
15
- /**
16
- * Todos to display (prop-based pattern)
17
- * Either client or todos should be provided
18
- */
19
- todos?: TodoItem[];
9
+ export interface ChatSecondaryPanelProps extends React.HTMLAttributes<HTMLDivElement> {
10
+ /**
11
+ * ACP Client for hook-based todo fetching (future support)
12
+ */
13
+ client?: AcpClient | null;
14
+ /**
15
+ * Todos to display (prop-based pattern)
16
+ * Either client or todos should be provided
17
+ */
18
+ todos?: TodoItem[];
20
19
  }
21
- export declare const ChatSecondaryPanel: React.ForwardRefExoticComponent<
22
- ChatSecondaryPanelProps & React.RefAttributes<HTMLDivElement>
23
- >;
20
+ export declare const ChatSecondaryPanel: React.ForwardRefExoticComponent<ChatSecondaryPanelProps & React.RefAttributes<HTMLDivElement>>;
@@ -1,121 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
2
  import * as React from "react";
2
3
  import { useEffect, useRef, useState } from "react";
3
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
4
  import { cn } from "../lib/utils.js";
5
5
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "./Tabs.js";
6
6
  import { TodoList } from "./TodoList.js";
7
- export const ChatSecondaryPanel = React.forwardRef(
8
- ({ client, todos, className, ...props }, ref) => {
9
- // For now, just use prop-based todos
10
- // Future: Add hook to get todos from store when available
11
- const todosToDisplay = todos || [];
12
- const [activeTab, setActiveTab] = useState("todo");
13
- const containerRef = useRef(null);
14
- const activeTabElementRef = useRef(null);
15
- useEffect(() => {
16
- const updateClipPath = () => {
17
- const container = containerRef.current;
18
- if (activeTab && container) {
19
- const activeTabElement = activeTabElementRef.current;
20
- if (activeTabElement) {
21
- const containerRect = container.getBoundingClientRect();
22
- const tabRect = activeTabElement.getBoundingClientRect();
23
- const offsetLeft = tabRect.left - containerRect.left;
24
- const offsetWidth = tabRect.width;
25
- const clipLeftPercent = (offsetLeft / containerRect.width) * 100;
26
- const clipRightPercent =
27
- 100 - ((offsetLeft + offsetWidth) / containerRect.width) * 100;
28
- container.style.clipPath = `inset(0 ${clipRightPercent.toFixed(2)}% 0 ${clipLeftPercent.toFixed(2)}% round 999px)`;
29
- }
30
- }
31
- };
32
- // Small delay to ensure DOM is ready
33
- const timeoutId = setTimeout(updateClipPath, 0);
34
- return () => clearTimeout(timeoutId);
35
- }, [activeTab]);
36
- const tabs = [
37
- { id: "todo", label: "To-Do List" },
38
- { id: "files", label: "Files" },
39
- { id: "database", label: "Database" },
40
- ];
41
- return _jsx("div", {
42
- ref: ref,
43
- className: cn("select-none", className),
44
- ...props,
45
- children: _jsxs(Tabs, {
46
- value: activeTab,
47
- onValueChange: setActiveTab,
48
- className: "w-full",
49
- children: [
50
- _jsxs("div", {
51
- className: "relative mb-4 border-border",
52
- children: [
53
- _jsx(TabsList, {
54
- className:
55
- "bg-transparent p-0 h-auto rounded-none w-full border-none",
56
- children: tabs.map((tab) =>
57
- _jsx(
58
- TabsTrigger,
59
- {
60
- value: tab.id,
61
- className:
62
- "px-3 py-1 text-sm font-[var(--font-family)] font-medium rounded-none text-foreground opacity-60 data-[state=active]:opacity-100 data-[state=active]:bg-transparent data-[state=active]:shadow-none",
63
- children: tab.label,
64
- },
65
- tab.id,
66
- ),
67
- ),
68
- }),
69
- _jsx("div", {
70
- ref: containerRef,
71
- className:
72
- "absolute top-0 left-0 w-full overflow-hidden z-10 pointer-events-none",
73
- style: {
74
- clipPath: "inset(0 100% 0 0% round 999px)",
75
- transition: "clip-path 0.25s ease-out",
76
- },
77
- children: _jsx(TabsList, {
78
- className:
79
- "bg-secondary p-0 h-auto rounded-none w-full border-none",
80
- children: tabs.map((tab) =>
81
- _jsx(
82
- TabsTrigger,
83
- {
84
- value: tab.id,
85
- ref: activeTab === tab.id ? activeTabElementRef : null,
86
- className:
87
- "px-3 py-1 text-sm font-[var(--font-family)] font-medium rounded-none text-primary bg-transparent data-[state=active]:shadow-none shadow-none",
88
- tabIndex: -1,
89
- children: tab.label,
90
- },
91
- tab.id,
92
- ),
93
- ),
94
- }),
95
- }),
96
- ],
97
- }),
98
- _jsx(TabsContent, {
99
- value: "todo",
100
- children: _jsx(TodoList, { todos: todosToDisplay }),
101
- }),
102
- _jsx(TabsContent, {
103
- value: "files",
104
- children: _jsx("div", {
105
- className: "text-sm text-foreground opacity-60 italic",
106
- children: "Files tab coming soon...",
107
- }),
108
- }),
109
- _jsx(TabsContent, {
110
- value: "database",
111
- children: _jsx("div", {
112
- className: "text-sm text-foreground opacity-60 italic",
113
- children: "Database tab coming soon...",
114
- }),
115
- }),
116
- ],
117
- }),
118
- });
119
- },
120
- );
7
+ export const ChatSecondaryPanel = React.forwardRef(({ client, todos, className, ...props }, ref) => {
8
+ // For now, just use prop-based todos
9
+ // Future: Add hook to get todos from store when available
10
+ const todosToDisplay = todos || [];
11
+ const [activeTab, setActiveTab] = useState("todo");
12
+ const containerRef = useRef(null);
13
+ const activeTabElementRef = useRef(null);
14
+ useEffect(() => {
15
+ const updateClipPath = () => {
16
+ const container = containerRef.current;
17
+ if (activeTab && container) {
18
+ const activeTabElement = activeTabElementRef.current;
19
+ if (activeTabElement) {
20
+ const containerRect = container.getBoundingClientRect();
21
+ const tabRect = activeTabElement.getBoundingClientRect();
22
+ const offsetLeft = tabRect.left - containerRect.left;
23
+ const offsetWidth = tabRect.width;
24
+ const clipLeftPercent = (offsetLeft / containerRect.width) * 100;
25
+ const clipRightPercent = 100 - ((offsetLeft + offsetWidth) / containerRect.width) * 100;
26
+ container.style.clipPath = `inset(0 ${clipRightPercent.toFixed(2)}% 0 ${clipLeftPercent.toFixed(2)}% round 999px)`;
27
+ }
28
+ }
29
+ };
30
+ // Small delay to ensure DOM is ready
31
+ const timeoutId = setTimeout(updateClipPath, 0);
32
+ return () => clearTimeout(timeoutId);
33
+ }, [activeTab]);
34
+ const tabs = [
35
+ { id: "todo", label: "To-Do List" },
36
+ { id: "files", label: "Files" },
37
+ { id: "database", label: "Database" },
38
+ ];
39
+ return (_jsx("div", { ref: ref, className: cn("select-none", className), ...props, children: _jsxs(Tabs, { value: activeTab, onValueChange: setActiveTab, className: "w-full", children: [_jsxs("div", { className: "relative mb-4 border-border", children: [_jsx(TabsList, { className: "bg-transparent p-0 h-auto rounded-none w-full border-none", children: tabs.map((tab) => (_jsx(TabsTrigger, { value: tab.id, className: "px-3 py-1 text-sm font-[var(--font-family)] font-medium rounded-none text-foreground opacity-60 data-[state=active]:opacity-100 data-[state=active]:bg-transparent data-[state=active]:shadow-none", children: tab.label }, tab.id))) }), _jsx("div", { ref: containerRef, className: "absolute top-0 left-0 w-full overflow-hidden z-10 pointer-events-none", style: {
40
+ clipPath: "inset(0 100% 0 0% round 999px)",
41
+ transition: "clip-path 0.25s ease-out",
42
+ }, children: _jsx(TabsList, { className: "bg-secondary p-0 h-auto rounded-none w-full border-none", children: tabs.map((tab) => (_jsx(TabsTrigger, { value: tab.id, ref: activeTab === tab.id ? activeTabElementRef : null, className: "px-3 py-1 text-sm font-[var(--font-family)] font-medium rounded-none text-primary bg-transparent data-[state=active]:shadow-none shadow-none", tabIndex: -1, children: tab.label }, tab.id))) }) })] }), _jsx(TabsContent, { value: "todo", children: _jsx(TodoList, { todos: todosToDisplay }) }), _jsx(TabsContent, { value: "files", children: _jsx("div", { className: "text-sm text-foreground opacity-60 italic", children: "Files tab coming soon..." }) }), _jsx(TabsContent, { value: "database", children: _jsx("div", { className: "text-sm text-foreground opacity-60 italic", children: "Database tab coming soon..." }) })] }) }));
43
+ });
121
44
  ChatSecondaryPanel.displayName = "ChatSecondaryPanel";