@townco/ui 0.1.0
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.
- package/README.md +175 -0
- package/dist/core/hooks/index.d.ts +6 -0
- package/dist/core/hooks/index.d.ts.map +1 -0
- package/dist/core/hooks/index.js +6 -0
- package/dist/core/hooks/index.js.map +1 -0
- package/dist/core/hooks/use-chat-input.d.ts +23 -0
- package/dist/core/hooks/use-chat-input.d.ts.map +1 -0
- package/dist/core/hooks/use-chat-input.js +63 -0
- package/dist/core/hooks/use-chat-input.js.map +1 -0
- package/dist/core/hooks/use-chat-messages.d.ts +17 -0
- package/dist/core/hooks/use-chat-messages.d.ts.map +1 -0
- package/dist/core/hooks/use-chat-messages.js +121 -0
- package/dist/core/hooks/use-chat-messages.js.map +1 -0
- package/dist/core/hooks/use-chat-session.d.ts +11 -0
- package/dist/core/hooks/use-chat-session.d.ts.map +1 -0
- package/dist/core/hooks/use-chat-session.js +87 -0
- package/dist/core/hooks/use-chat-session.js.map +1 -0
- package/dist/core/hooks/use-media-query.d.ts +39 -0
- package/dist/core/hooks/use-media-query.js +80 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/schemas/chat.d.ts +78 -0
- package/dist/core/schemas/chat.d.ts.map +1 -0
- package/dist/core/schemas/chat.js +49 -0
- package/dist/core/schemas/chat.js.map +1 -0
- package/dist/core/schemas/index.d.ts +4 -0
- package/dist/core/schemas/index.d.ts.map +1 -0
- package/dist/core/schemas/index.js +4 -0
- package/dist/core/schemas/index.js.map +1 -0
- package/dist/core/store/chat-store.d.ts +30 -0
- package/dist/core/store/chat-store.d.ts.map +1 -0
- package/dist/core/store/chat-store.js +56 -0
- package/dist/core/store/chat-store.js.map +1 -0
- package/dist/gui/components/Button.d.ts +11 -0
- package/dist/gui/components/Button.d.ts.map +1 -0
- package/dist/gui/components/Button.js +33 -0
- package/dist/gui/components/Button.js.map +1 -0
- package/dist/gui/components/Card.d.ts +8 -0
- package/dist/gui/components/Card.d.ts.map +1 -0
- package/dist/gui/components/Card.js +16 -0
- package/dist/gui/components/Card.js.map +1 -0
- package/dist/gui/components/ChatHeader.d.ts +38 -0
- package/dist/gui/components/ChatHeader.js +84 -0
- package/dist/gui/components/ChatInput.d.ts +42 -0
- package/dist/gui/components/ChatInput.d.ts.map +1 -0
- package/dist/gui/components/ChatInput.js +137 -0
- package/dist/gui/components/ChatInput.js.map +1 -0
- package/dist/gui/components/ChatInterface.d.ts +9 -0
- package/dist/gui/components/ChatInterface.d.ts.map +1 -0
- package/dist/gui/components/ChatInterface.js +132 -0
- package/dist/gui/components/ChatInterface.js.map +1 -0
- package/dist/gui/components/ChatLayout.d.ts +52 -0
- package/dist/gui/components/ChatLayout.js +105 -0
- package/dist/gui/components/ChatPanelTabContent.d.ts +18 -0
- package/dist/gui/components/ChatPanelTabContent.js +15 -0
- package/dist/gui/components/ChatPreview.d.ts +9 -0
- package/dist/gui/components/ChatPreview.d.ts.map +1 -0
- package/dist/gui/components/ChatPreview.js +164 -0
- package/dist/gui/components/ChatPreview.js.map +1 -0
- package/dist/gui/components/ChatSecondaryPanel.d.ts +20 -0
- package/dist/gui/components/ChatSecondaryPanel.d.ts.map +1 -0
- package/dist/gui/components/ChatSecondaryPanel.js +44 -0
- package/dist/gui/components/ChatSecondaryPanel.js.map +1 -0
- package/dist/gui/components/ChatSidebar.d.ts +14 -0
- package/dist/gui/components/ChatSidebar.js +23 -0
- package/dist/gui/components/ChatStatus.d.ts +6 -0
- package/dist/gui/components/ChatStatus.d.ts.map +1 -0
- package/dist/gui/components/ChatStatus.js +38 -0
- package/dist/gui/components/ChatStatus.js.map +1 -0
- package/dist/gui/components/ChatView.d.ts +6 -0
- package/dist/gui/components/ChatView.d.ts.map +1 -0
- package/dist/gui/components/ChatView.js +13 -0
- package/dist/gui/components/ChatView.js.map +1 -0
- package/dist/gui/components/ConfigPanel.d.ts +16 -0
- package/dist/gui/components/ConfigPanel.d.ts.map +1 -0
- package/dist/gui/components/ConfigPanel.js +48 -0
- package/dist/gui/components/ConfigPanel.js.map +1 -0
- package/dist/gui/components/Conversation.d.ts +20 -0
- package/dist/gui/components/Conversation.d.ts.map +1 -0
- package/dist/gui/components/Conversation.js +87 -0
- package/dist/gui/components/Conversation.js.map +1 -0
- package/dist/gui/components/Dialog.d.ts +19 -0
- package/dist/gui/components/Dialog.d.ts.map +1 -0
- package/dist/gui/components/Dialog.js +22 -0
- package/dist/gui/components/Dialog.js.map +1 -0
- package/dist/gui/components/DropdownMenu.d.ts +27 -0
- package/dist/gui/components/DropdownMenu.js +68 -0
- package/dist/gui/components/HeightTransition.d.ts +10 -0
- package/dist/gui/components/HeightTransition.d.ts.map +1 -0
- package/dist/gui/components/HeightTransition.js +80 -0
- package/dist/gui/components/HeightTransition.js.map +1 -0
- package/dist/gui/components/Input.d.ts +9 -0
- package/dist/gui/components/Input.d.ts.map +1 -0
- package/dist/gui/components/Input.js +21 -0
- package/dist/gui/components/Input.js.map +1 -0
- package/dist/gui/components/InputBox.d.ts +14 -0
- package/dist/gui/components/InputBox.d.ts.map +1 -0
- package/dist/gui/components/InputBox.js +18 -0
- package/dist/gui/components/InputBox.js.map +1 -0
- package/dist/gui/components/Label.d.ts +4 -0
- package/dist/gui/components/Label.d.ts.map +1 -0
- package/dist/gui/components/Label.js +7 -0
- package/dist/gui/components/Label.js.map +1 -0
- package/dist/gui/components/MarkdownRenderer.d.ts +6 -0
- package/dist/gui/components/MarkdownRenderer.d.ts.map +1 -0
- package/dist/gui/components/MarkdownRenderer.js +86 -0
- package/dist/gui/components/MarkdownRenderer.js.map +1 -0
- package/dist/gui/components/Message.d.ts +26 -0
- package/dist/gui/components/Message.d.ts.map +1 -0
- package/dist/gui/components/Message.js +33 -0
- package/dist/gui/components/Message.js.map +1 -0
- package/dist/gui/components/MessageContent.d.ts +26 -0
- package/dist/gui/components/MessageContent.d.ts.map +1 -0
- package/dist/gui/components/MessageContent.js +104 -0
- package/dist/gui/components/MessageContent.js.map +1 -0
- package/dist/gui/components/MessageList.d.ts +6 -0
- package/dist/gui/components/MessageList.d.ts.map +1 -0
- package/dist/gui/components/MessageList.js +1 -0
- package/dist/gui/components/MessageList.js.map +1 -0
- package/dist/gui/components/PlaygroundLayout.d.ts +10 -0
- package/dist/gui/components/PlaygroundLayout.d.ts.map +1 -0
- package/dist/gui/components/PlaygroundLayout.js +18 -0
- package/dist/gui/components/PlaygroundLayout.js.map +1 -0
- package/dist/gui/components/Reasoning.d.ts +31 -0
- package/dist/gui/components/Reasoning.d.ts.map +1 -0
- package/dist/gui/components/Reasoning.js +70 -0
- package/dist/gui/components/Reasoning.js.map +1 -0
- package/dist/gui/components/Response.d.ts +16 -0
- package/dist/gui/components/Response.d.ts.map +1 -0
- package/dist/gui/components/Response.js +95 -0
- package/dist/gui/components/Response.js.map +1 -0
- package/dist/gui/components/Select.d.ts +13 -0
- package/dist/gui/components/Select.d.ts.map +1 -0
- package/dist/gui/components/Select.js +26 -0
- package/dist/gui/components/Select.js.map +1 -0
- package/dist/gui/components/Sonner.d.ts +5 -0
- package/dist/gui/components/Sonner.js +23 -0
- package/dist/gui/components/StatusBar.d.ts +8 -0
- package/dist/gui/components/StatusBar.d.ts.map +1 -0
- package/dist/gui/components/StatusBar.js +11 -0
- package/dist/gui/components/StatusBar.js.map +1 -0
- package/dist/gui/components/Tabs.d.ts +7 -0
- package/dist/gui/components/Tabs.d.ts.map +1 -0
- package/dist/gui/components/Tabs.js +12 -0
- package/dist/gui/components/Tabs.js.map +1 -0
- package/dist/gui/components/Task.d.ts +35 -0
- package/dist/gui/components/Task.d.ts.map +1 -0
- package/dist/gui/components/Task.js +37 -0
- package/dist/gui/components/Task.js.map +1 -0
- package/dist/gui/components/Textarea.d.ts +11 -0
- package/dist/gui/components/Textarea.d.ts.map +1 -0
- package/dist/gui/components/Textarea.js +51 -0
- package/dist/gui/components/Textarea.js.map +1 -0
- package/dist/gui/components/ThinkingBlock.d.ts +12 -0
- package/dist/gui/components/ThinkingBlock.d.ts.map +1 -0
- package/dist/gui/components/ThinkingBlock.js +40 -0
- package/dist/gui/components/ThinkingBlock.js.map +1 -0
- package/dist/gui/components/TodoList.d.ts +20 -0
- package/dist/gui/components/TodoList.d.ts.map +1 -0
- package/dist/gui/components/TodoList.js +11 -0
- package/dist/gui/components/TodoList.js.map +1 -0
- package/dist/gui/components/TodoListItem.d.ts +10 -0
- package/dist/gui/components/TodoListItem.d.ts.map +1 -0
- package/dist/gui/components/TodoListItem.js +7 -0
- package/dist/gui/components/TodoListItem.js.map +1 -0
- package/dist/gui/components/index.d.ts +23 -0
- package/dist/gui/components/index.d.ts.map +1 -0
- package/dist/gui/components/index.js +28 -0
- package/dist/gui/components/index.js.map +1 -0
- package/dist/gui/index.d.ts +2 -0
- package/dist/gui/index.d.ts.map +1 -0
- package/dist/gui/index.js +4 -0
- package/dist/gui/index.js.map +1 -0
- package/dist/gui/lib/utils.d.ts +2 -0
- package/dist/gui/lib/utils.d.ts.map +1 -0
- package/dist/gui/lib/utils.js +5 -0
- package/dist/gui/lib/utils.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +0 -0
- package/dist/index.test.js +1 -0
- package/dist/sdk/client/acp-client.d.ts +84 -0
- package/dist/sdk/client/acp-client.d.ts.map +1 -0
- package/dist/sdk/client/acp-client.js +225 -0
- package/dist/sdk/client/acp-client.js.map +1 -0
- package/dist/sdk/client/index.d.ts +4 -0
- package/dist/sdk/client/index.d.ts.map +1 -0
- package/dist/sdk/client/index.js +4 -0
- package/dist/sdk/client/index.js.map +1 -0
- package/dist/sdk/index.d.ts +9 -0
- package/dist/sdk/index.d.ts.map +1 -0
- package/dist/sdk/index.js +9 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/schemas/agent.d.ts +87 -0
- package/dist/sdk/schemas/agent.d.ts.map +1 -0
- package/dist/sdk/schemas/agent.js +50 -0
- package/dist/sdk/schemas/agent.js.map +1 -0
- package/dist/sdk/schemas/index.d.ts +6 -0
- package/dist/sdk/schemas/index.d.ts.map +1 -0
- package/dist/sdk/schemas/index.js +6 -0
- package/dist/sdk/schemas/index.js.map +1 -0
- package/dist/sdk/schemas/message.d.ts +195 -0
- package/dist/sdk/schemas/message.d.ts.map +1 -0
- package/dist/sdk/schemas/message.js +95 -0
- package/dist/sdk/schemas/message.js.map +1 -0
- package/dist/sdk/schemas/session.d.ts +158 -0
- package/dist/sdk/schemas/session.d.ts.map +1 -0
- package/dist/sdk/schemas/session.js +54 -0
- package/dist/sdk/schemas/session.js.map +1 -0
- package/dist/sdk/transports/http.d.ts +63 -0
- package/dist/sdk/transports/http.d.ts.map +1 -0
- package/dist/sdk/transports/http.js +476 -0
- package/dist/sdk/transports/http.js.map +1 -0
- package/dist/sdk/transports/index.d.ts +7 -0
- package/dist/sdk/transports/index.d.ts.map +1 -0
- package/dist/sdk/transports/index.js +7 -0
- package/dist/sdk/transports/index.js.map +1 -0
- package/dist/sdk/transports/stdio.d.ts +28 -0
- package/dist/sdk/transports/stdio.d.ts.map +1 -0
- package/dist/sdk/transports/stdio.js +294 -0
- package/dist/sdk/transports/stdio.js.map +1 -0
- package/dist/sdk/transports/types.d.ts +63 -0
- package/dist/sdk/transports/types.d.ts.map +1 -0
- package/dist/sdk/transports/types.js +1 -0
- package/dist/sdk/transports/types.js.map +1 -0
- package/dist/sdk/transports/websocket.d.ts +20 -0
- package/dist/sdk/transports/websocket.d.ts.map +1 -0
- package/dist/sdk/transports/websocket.js +52 -0
- package/dist/sdk/transports/websocket.js.map +1 -0
- package/dist/tui/components/ChatView.d.ts +5 -0
- package/dist/tui/components/ChatView.d.ts.map +1 -0
- package/dist/tui/components/ChatView.js +24 -0
- package/dist/tui/components/ChatView.js.map +1 -0
- package/dist/tui/components/GameOfLife.d.ts +1 -0
- package/dist/tui/components/GameOfLife.d.ts.map +1 -0
- package/dist/tui/components/GameOfLife.js +50 -0
- package/dist/tui/components/GameOfLife.js.map +1 -0
- package/dist/tui/components/InputBox.d.ts +13 -0
- package/dist/tui/components/InputBox.d.ts.map +1 -0
- package/dist/tui/components/InputBox.js +15 -0
- package/dist/tui/components/InputBox.js.map +1 -0
- package/dist/tui/components/MessageList.d.ts +5 -0
- package/dist/tui/components/MessageList.d.ts.map +1 -0
- package/dist/tui/components/MessageList.js +16 -0
- package/dist/tui/components/MessageList.js.map +1 -0
- package/dist/tui/components/MultiSelect.d.ts +13 -0
- package/dist/tui/components/MultiSelect.js +72 -0
- package/dist/tui/components/ReadlineInput.d.ts +8 -0
- package/dist/tui/components/ReadlineInput.d.ts.map +1 -0
- package/dist/tui/components/ReadlineInput.js +240 -0
- package/dist/tui/components/ReadlineInput.js.map +1 -0
- package/dist/tui/components/SingleSelect.d.ts +13 -0
- package/dist/tui/components/SingleSelect.js +46 -0
- package/dist/tui/components/StatusBar.d.ts +9 -0
- package/dist/tui/components/StatusBar.d.ts.map +1 -0
- package/dist/tui/components/StatusBar.js +82 -0
- package/dist/tui/components/StatusBar.js.map +1 -0
- package/dist/tui/components/index.d.ts +11 -0
- package/dist/tui/components/index.d.ts.map +1 -0
- package/dist/tui/components/index.js +11 -0
- package/dist/tui/components/index.js.map +1 -0
- package/dist/tui/index.d.ts +7 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +7 -0
- package/dist/tui/index.js.map +1 -0
- package/package.json +86 -0
- package/src/styles/global.css +152 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { useChatInput as useCoreChatInput } from "../../core/hooks/use-chat-input.js";
|
|
5
|
+
import { useChatStore } from "../../core/store/chat-store.js";
|
|
6
|
+
import { cn } from "../lib/utils.js";
|
|
7
|
+
import { Button } from "./Button.js";
|
|
8
|
+
const ChatInputContext = React.createContext(undefined);
|
|
9
|
+
const useChatInputContext = () => {
|
|
10
|
+
const context = React.useContext(ChatInputContext);
|
|
11
|
+
if (!context) {
|
|
12
|
+
throw new Error("ChatInput components must be used within ChatInput.Root");
|
|
13
|
+
}
|
|
14
|
+
return context;
|
|
15
|
+
};
|
|
16
|
+
const ChatInputRoot = React.forwardRef(({ client, value: valueProp, onChange: onChangeProp, onSubmit: onSubmitProp, disabled = false, isSubmitting: isSubmittingProp, submitOnEnter = true, className, children, ...props }, ref) => {
|
|
17
|
+
const textareaRef = React.useRef(null);
|
|
18
|
+
// Always call hooks unconditionally (React rules)
|
|
19
|
+
const hookData = useCoreChatInput(client ?? null);
|
|
20
|
+
const storeIsStreaming = useChatStore((state) => state.isStreaming);
|
|
21
|
+
// Choose data source based on whether client is provided
|
|
22
|
+
const value = hookData ? hookData.value : valueProp || "";
|
|
23
|
+
const onChange = hookData ? hookData.onChange : onChangeProp || (() => { });
|
|
24
|
+
const onSubmit = hookData
|
|
25
|
+
? hookData.onSubmit
|
|
26
|
+
: onSubmitProp || (async () => { });
|
|
27
|
+
const isSubmitting = hookData
|
|
28
|
+
? hookData.isSubmitting || storeIsStreaming
|
|
29
|
+
: isSubmittingProp || false;
|
|
30
|
+
const handleSubmit = async (e) => {
|
|
31
|
+
e.preventDefault();
|
|
32
|
+
if (value.trim() && !isSubmitting && !disabled) {
|
|
33
|
+
await onSubmit();
|
|
34
|
+
// Restore focus to textarea after submit
|
|
35
|
+
setTimeout(() => {
|
|
36
|
+
textareaRef.current?.focus();
|
|
37
|
+
}, 0);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
// Expose textarea ref to children via context
|
|
41
|
+
React.useEffect(() => {
|
|
42
|
+
const textarea = document.querySelector('textarea[name="chat-input"]');
|
|
43
|
+
if (textarea && textareaRef.current !== textarea) {
|
|
44
|
+
textareaRef.current = textarea;
|
|
45
|
+
}
|
|
46
|
+
}, []);
|
|
47
|
+
// Reset textarea height when value becomes empty (after submit)
|
|
48
|
+
React.useEffect(() => {
|
|
49
|
+
if (!value && textareaRef.current) {
|
|
50
|
+
textareaRef.current.style.height = "auto";
|
|
51
|
+
textareaRef.current.style.overflowY = "hidden";
|
|
52
|
+
}
|
|
53
|
+
}, [value]);
|
|
54
|
+
return (_jsx(ChatInputContext.Provider, { value: {
|
|
55
|
+
value,
|
|
56
|
+
onChange,
|
|
57
|
+
onSubmit,
|
|
58
|
+
disabled,
|
|
59
|
+
isSubmitting,
|
|
60
|
+
submitOnEnter,
|
|
61
|
+
}, children: _jsx("form", { ref: ref, onSubmit: handleSubmit, className: cn("w-full divide-y overflow-hidden rounded-xl border bg-background shadow-sm", className), ...props, children: children }) }));
|
|
62
|
+
});
|
|
63
|
+
ChatInputRoot.displayName = "ChatInput.Root";
|
|
64
|
+
const ChatInputField = React.forwardRef(({ asChild = false, className, onKeyDown, children, ...props }, ref) => {
|
|
65
|
+
const { value, onChange, onSubmit, disabled, isSubmitting, submitOnEnter } = useChatInputContext();
|
|
66
|
+
const textareaRef = React.useRef(null);
|
|
67
|
+
const handleRef = React.useCallback((node) => {
|
|
68
|
+
textareaRef.current = node;
|
|
69
|
+
if (typeof ref === "function") {
|
|
70
|
+
ref(node);
|
|
71
|
+
}
|
|
72
|
+
else if (ref) {
|
|
73
|
+
ref.current = node;
|
|
74
|
+
}
|
|
75
|
+
}, [ref]);
|
|
76
|
+
const handleKeyDown = (e) => {
|
|
77
|
+
// Handle Enter without Shift - only submit if not already submitting
|
|
78
|
+
if (submitOnEnter && e.key === "Enter" && !e.shiftKey) {
|
|
79
|
+
// Only prevent default and submit if conditions are met
|
|
80
|
+
if (value.trim() && !isSubmitting && !disabled) {
|
|
81
|
+
e.preventDefault();
|
|
82
|
+
onSubmit();
|
|
83
|
+
}
|
|
84
|
+
else if (isSubmitting || disabled) {
|
|
85
|
+
// Block Enter when submitting or disabled - don't add newline
|
|
86
|
+
e.preventDefault();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
onKeyDown?.(e);
|
|
90
|
+
};
|
|
91
|
+
const handleChange = (e) => {
|
|
92
|
+
onChange(e.target.value);
|
|
93
|
+
// Auto-resize
|
|
94
|
+
const textarea = textareaRef.current;
|
|
95
|
+
if (!textarea)
|
|
96
|
+
return;
|
|
97
|
+
textarea.style.height = "auto";
|
|
98
|
+
const newHeight = Math.min(textarea.scrollHeight, 164);
|
|
99
|
+
textarea.style.height = `${newHeight}px`;
|
|
100
|
+
if (textarea.scrollHeight > 164) {
|
|
101
|
+
textarea.style.overflowY = "auto";
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
textarea.style.overflowY = "hidden";
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const fieldProps = {
|
|
108
|
+
ref: handleRef,
|
|
109
|
+
name: "chat-input",
|
|
110
|
+
value,
|
|
111
|
+
onChange: handleChange,
|
|
112
|
+
onKeyDown: handleKeyDown,
|
|
113
|
+
disabled: disabled,
|
|
114
|
+
...props,
|
|
115
|
+
};
|
|
116
|
+
if (asChild && React.isValidElement(children)) {
|
|
117
|
+
return React.cloneElement(children, fieldProps);
|
|
118
|
+
}
|
|
119
|
+
return (_jsx("textarea", { ...fieldProps, className: cn("w-full resize-none rounded-none border-none p-3 shadow-none", "outline-none ring-0 field-sizing-content max-h-[6lh]", "bg-transparent dark:bg-transparent focus-visible:ring-0", "text-sm placeholder:text-muted-foreground", "disabled:cursor-not-allowed disabled:opacity-50", className) }));
|
|
120
|
+
});
|
|
121
|
+
ChatInputField.displayName = "ChatInput.Field";
|
|
122
|
+
const ChatInputSubmit = React.forwardRef(({ asChild = false, className, disabled: disabledProp, children, ...props }, ref) => {
|
|
123
|
+
const { value, disabled, isSubmitting } = useChatInputContext();
|
|
124
|
+
const isDisabled = disabledProp || disabled || isSubmitting || !value.trim();
|
|
125
|
+
const Comp = asChild ? Slot : Button;
|
|
126
|
+
return (_jsx(Comp, { ref: ref, type: "submit", disabled: isDisabled, size: "icon", className: cn(!asChild &&
|
|
127
|
+
"gap-1.5 rounded-lg bg-transparent text-foreground hover:bg-transparent", className), ...props, children: children }));
|
|
128
|
+
});
|
|
129
|
+
ChatInputSubmit.displayName = "ChatInput.Submit";
|
|
130
|
+
const ChatInputToolbar = React.forwardRef(({ className, children, ...props }, ref) => {
|
|
131
|
+
return (_jsx("div", { ref: ref, className: cn("flex items-center justify-between p-1", className), ...props, children: children }));
|
|
132
|
+
});
|
|
133
|
+
ChatInputToolbar.displayName = "ChatInput.Toolbar";
|
|
134
|
+
/* -------------------------------------------------------------------------------------------------
|
|
135
|
+
* Exports
|
|
136
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
137
|
+
export { ChatInputRoot as Root, ChatInputField as Field, ChatInputSubmit as Submit, ChatInputToolbar as Toolbar, };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatInput.js","sourceRoot":"","sources":["../../../src/gui/components/ChatInput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type DisplayMessage } from "./MessageList.js";
|
|
2
|
+
interface ChatInterfaceProps {
|
|
3
|
+
initialMessages?: DisplayMessage[];
|
|
4
|
+
thinkingDisplayStyle?: "collapsible" | "inline";
|
|
5
|
+
status?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function ChatInterface({ initialMessages, thinkingDisplayStyle, status, }: ChatInterfaceProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=ChatInterface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatInterface.d.ts","sourceRoot":"","sources":["../../../src/gui/components/ChatInterface.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAQpE,UAAU,kBAAkB;IAC1B,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,oBAAoB,CAAC,EAAE,aAAa,GAAG,QAAQ,CAAC;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA2FD,wBAAgB,aAAa,CAAC,EAC5B,eAAiC,EACjC,oBAAoC,EACpC,MAAoB,GACrB,EAAE,kBAAkB,2CA+FpB"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
3
|
+
import { ChevronDown } from "lucide-react";
|
|
4
|
+
import { MessageList } from "./MessageList.js";
|
|
5
|
+
import { ChatStatus } from "./ChatStatus.js";
|
|
6
|
+
import { ChatSecondaryPanel } from "./ChatSecondaryPanel.js";
|
|
7
|
+
import { HeightTransition } from "./HeightTransition.js";
|
|
8
|
+
import { ChatInput } from "./ChatInput.js";
|
|
9
|
+
const SAMPLE_TODOS = [
|
|
10
|
+
{
|
|
11
|
+
id: "1",
|
|
12
|
+
text: "Identify the last 25 Winter Olympics host countries",
|
|
13
|
+
status: "completed",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: "2",
|
|
17
|
+
text: "For each host country, find the tallest mountain",
|
|
18
|
+
status: "in_progress",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: "3",
|
|
22
|
+
text: "Gather key details for each mountain (name, elevation, location)",
|
|
23
|
+
status: "pending",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: "4",
|
|
27
|
+
text: "Verify information using reliable sources (geographical databases, official records)",
|
|
28
|
+
status: "pending",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "5",
|
|
32
|
+
text: "Compile findings into a summary table or document",
|
|
33
|
+
status: "pending",
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
const SAMPLE_MESSAGES = [
|
|
37
|
+
{
|
|
38
|
+
id: "msg-1",
|
|
39
|
+
role: "user",
|
|
40
|
+
content: "Hello! Can you help me understand how to use markdown?",
|
|
41
|
+
timestamp: new Date().toISOString(),
|
|
42
|
+
isStreaming: false,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "msg-2",
|
|
46
|
+
role: "assistant",
|
|
47
|
+
content: `Sure! Markdown is a lightweight markup language. Here are some basics:
|
|
48
|
+
|
|
49
|
+
## Headings
|
|
50
|
+
Use \`#\` for headings. More \`#\` symbols make smaller headings.
|
|
51
|
+
|
|
52
|
+
## Lists
|
|
53
|
+
- Unordered lists use dashes
|
|
54
|
+
- Or asterisks
|
|
55
|
+
- Or plus signs
|
|
56
|
+
|
|
57
|
+
1. Ordered lists
|
|
58
|
+
2. Use numbers
|
|
59
|
+
3. Like this
|
|
60
|
+
|
|
61
|
+
## Code
|
|
62
|
+
Inline code uses \`backticks\` and code blocks use triple backticks:
|
|
63
|
+
|
|
64
|
+
\`\`\`javascript
|
|
65
|
+
function hello() {
|
|
66
|
+
console.log("Hello world!");
|
|
67
|
+
}
|
|
68
|
+
\`\`\`
|
|
69
|
+
|
|
70
|
+
## Links and emphasis
|
|
71
|
+
[This is a link](https://example.com)
|
|
72
|
+
|
|
73
|
+
You can make text **bold** or *italic*.
|
|
74
|
+
|
|
75
|
+
> Blockquotes use the > character
|
|
76
|
+
|
|
77
|
+
## Tables
|
|
78
|
+
| Header 1 | Header 2 |
|
|
79
|
+
|----------|----------|
|
|
80
|
+
| Cell 1 | Cell 2 |
|
|
81
|
+
| Cell 3 | Cell 4 |`,
|
|
82
|
+
timestamp: new Date().toISOString(),
|
|
83
|
+
isStreaming: false,
|
|
84
|
+
metadata: {
|
|
85
|
+
thinking: "Let me provide a comprehensive overview of markdown syntax...",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "msg-3",
|
|
90
|
+
role: "user",
|
|
91
|
+
content: "That's really helpful, thank you!",
|
|
92
|
+
timestamp: new Date().toISOString(),
|
|
93
|
+
isStreaming: false,
|
|
94
|
+
},
|
|
95
|
+
];
|
|
96
|
+
export function ChatInterface({ initialMessages = SAMPLE_MESSAGES, thinkingDisplayStyle = "collapsible", status = "Connected", }) {
|
|
97
|
+
const [messages, setMessages] = useState(initialMessages);
|
|
98
|
+
const [currentStatus, setCurrentStatus] = useState(status);
|
|
99
|
+
const [config, setConfig] = useState(null);
|
|
100
|
+
const [isHeaderExpanded, setIsHeaderExpanded] = useState(false);
|
|
101
|
+
const [todos] = useState(SAMPLE_TODOS);
|
|
102
|
+
// Listen for config and status updates from parent window
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
const handleMessage = (event) => {
|
|
105
|
+
if (event.data.type === "CONFIG_UPDATE") {
|
|
106
|
+
const newConfig = event.data.config;
|
|
107
|
+
setConfig(newConfig);
|
|
108
|
+
applyConfigToDocument(newConfig);
|
|
109
|
+
}
|
|
110
|
+
else if (event.data.type === "STATUS_UPDATE") {
|
|
111
|
+
setCurrentStatus(event.data.status);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
window.addEventListener("message", handleMessage);
|
|
115
|
+
// Request config from parent on mount
|
|
116
|
+
if (window.parent !== window) {
|
|
117
|
+
window.parent.postMessage({ type: "REQUEST_CONFIG" }, "*");
|
|
118
|
+
}
|
|
119
|
+
return () => {
|
|
120
|
+
window.removeEventListener("message", handleMessage);
|
|
121
|
+
};
|
|
122
|
+
}, []);
|
|
123
|
+
const applyConfigToDocument = (cfg) => {
|
|
124
|
+
const root = document.documentElement;
|
|
125
|
+
root.setAttribute("data-theme", cfg.colorScheme);
|
|
126
|
+
root.style.setProperty("--color-accent", cfg.accentColor);
|
|
127
|
+
root.style.setProperty("--font-family", cfg.typography);
|
|
128
|
+
root.style.setProperty("--font-size", `${cfg.fontSize}px`);
|
|
129
|
+
};
|
|
130
|
+
return (_jsxs("div", { className: "flex flex-col h-screen bg-[var(--color-bg)] text-[var(--color-text)]", children: [_jsxs("div", { className: "relative border-b border-[var(--color-border)] bg-[var(--color-surface)] z-10", children: [_jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [_jsx("h1", { className: "text-xl font-semibold m-0", children: "Chat Interface" }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(ChatStatus, { children: currentStatus }), _jsx("button", { onClick: () => setIsHeaderExpanded(!isHeaderExpanded), className: "p-1 rounded hover:bg-[var(--color-bg)] transition-colors", "aria-label": isHeaderExpanded ? "Collapse header" : "Expand header", children: _jsx(ChevronDown, { className: `w-5 h-5 text-[var(--color-text)] transition-transform duration-200 ${isHeaderExpanded ? "rotate-180" : ""}` }) })] })] }), _jsx("div", { className: "absolute top-full left-0 right-0 z-20", children: _jsx(HeightTransition, { children: isHeaderExpanded && (_jsx("div", { className: "bg-[var(--color-surface)] border-b border-[var(--color-border)] px-6 py-4 shadow-lg", children: _jsx(ChatSecondaryPanel, { todos: todos }) })) }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto py-4", children: _jsx(MessageList, { messages: messages, thinkingDisplayStyle: config?.thinkingDisplayStyle || thinkingDisplayStyle }) }), _jsx("div", { className: "border-t border-[var(--color-border)] px-6 py-4 bg-[var(--color-surface)]", children: _jsx(ChatInput, { value: "", onChange: () => { }, onSubmit: () => { }, disabled: true, placeholder: "Type a message..." }) })] }));
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=ChatInterface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatInterface.js","sourceRoot":"","sources":["../../../src/gui/components/ChatInterface.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAuB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAU3C,MAAM,YAAY,GAAe;IAC/B;QACE,EAAE,EAAE,GAAG;QACP,IAAI,EAAE,qDAAqD;QAC3D,MAAM,EAAE,WAAW;KACpB;IACD;QACE,EAAE,EAAE,GAAG;QACP,IAAI,EAAE,kDAAkD;QACxD,MAAM,EAAE,aAAa;KACtB;IACD;QACE,EAAE,EAAE,GAAG;QACP,IAAI,EAAE,kEAAkE;QACxE,MAAM,EAAE,SAAS;KAClB;IACD;QACE,EAAE,EAAE,GAAG;QACP,IAAI,EAAE,sFAAsF;QAC5F,MAAM,EAAE,SAAS;KAClB;IACD;QACE,EAAE,EAAE,GAAG;QACP,IAAI,EAAE,mDAAmD;QACzD,MAAM,EAAE,SAAS;KAClB;CACF,CAAC;AAEF,MAAM,eAAe,GAAqB;IACxC;QACE,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,wDAAwD;QACjE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,WAAW,EAAE,KAAK;KACnB;IACD;QACE,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAkCW;QACpB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,WAAW,EAAE,KAAK;QAClB,QAAQ,EAAE;YACR,QAAQ,EAAE,+DAA+D;SAC1E;KACF;IACD;QACE,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,mCAAmC;QAC5C,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,WAAW,EAAE,KAAK;KACnB;CACF,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,EAC5B,eAAe,GAAG,eAAe,EACjC,oBAAoB,GAAG,aAAa,EACpC,MAAM,GAAG,WAAW,GACD;IACnB,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAmB,eAAe,CAAC,CAAC;IAC5E,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3D,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAqB,IAAI,CAAC,CAAC;IAC/D,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChE,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAa,YAAY,CAAC,CAAC;IAEnD,0DAA0D;IAC1D,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,aAAa,GAAG,CAAC,KAAmB,EAAE,EAAE;YAC5C,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;gBACxC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,MAAqB,CAAC;gBACnD,SAAS,CAAC,SAAS,CAAC,CAAC;gBACrB,qBAAqB,CAAC,SAAS,CAAC,CAAC;YACnC,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;gBAC/C,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACtC,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAElD,sCAAsC;QACtC,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC7B,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,GAAG,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACvD,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,qBAAqB,GAAG,CAAC,GAAgB,EAAE,EAAE;QACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe,CAAC;QACtC,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,gBAAgB,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;QAC1D,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,eAAe,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;QACxD,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,EAAE,GAAG,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC;IAC7D,CAAC,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAC,sEAAsE,aAEnF,eAAK,SAAS,EAAC,+EAA+E,aAC5F,eAAK,SAAS,EAAC,6CAA6C,aAC1D,aAAI,SAAS,EAAC,2BAA2B,+BAAoB,EAC7D,eAAK,SAAS,EAAC,yBAAyB,aACtC,KAAC,UAAU,cAAE,aAAa,GAAc,EACxC,iBACE,OAAO,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,CAAC,gBAAgB,CAAC,EACrD,SAAS,EAAC,0DAA0D,gBACxD,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,eAAe,YAElE,KAAC,WAAW,IACV,SAAS,EAAE,sEACT,gBAAgB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EACpC,EAAE,GACF,GACK,IACL,IACF,EAGN,cAAK,SAAS,EAAC,uCAAuC,YACpD,KAAC,gBAAgB,cACd,gBAAgB,IAAI,CACnB,cAAK,SAAS,EAAC,qFAAqF,YAClG,KAAC,kBAAkB,IAAC,KAAK,EAAE,KAAK,GAAI,GAChC,CACP,GACgB,GACf,IACF,EAGN,cAAK,SAAS,EAAC,6BAA6B,YAC1C,KAAC,WAAW,IACV,QAAQ,EAAE,QAAQ,EAClB,oBAAoB,EAClB,MAAM,EAAE,oBAAoB,IAAI,oBAAoB,GAEtD,GACE,EAGN,cAAK,SAAS,EAAC,2EAA2E,YACxF,KAAC,SAAS,IACR,KAAK,EAAC,EAAE,EACR,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,EAClB,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,EAClB,QAAQ,QACR,WAAW,EAAC,mBAAmB,GAC/B,GACE,IACF,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
type PanelSize = "hidden" | "small" | "large";
|
|
3
|
+
type PanelTabType = "todo" | "files" | "database";
|
|
4
|
+
interface ChatLayoutContextValue {
|
|
5
|
+
sidebarOpen: boolean;
|
|
6
|
+
setSidebarOpen: (open: boolean) => void;
|
|
7
|
+
panelSize: PanelSize;
|
|
8
|
+
setPanelSize: (size: PanelSize) => void;
|
|
9
|
+
activeTab: PanelTabType;
|
|
10
|
+
setActiveTab: (tab: PanelTabType) => void;
|
|
11
|
+
}
|
|
12
|
+
declare const useChatLayoutContext: () => ChatLayoutContextValue;
|
|
13
|
+
export interface ChatLayoutRootProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
14
|
+
/** Initial sidebar open state */
|
|
15
|
+
defaultSidebarOpen?: boolean;
|
|
16
|
+
/** Initial panel size state */
|
|
17
|
+
defaultPanelSize?: PanelSize;
|
|
18
|
+
/** Initial active tab */
|
|
19
|
+
defaultActiveTab?: PanelTabType;
|
|
20
|
+
}
|
|
21
|
+
declare const ChatLayoutRoot: React.ForwardRefExoticComponent<ChatLayoutRootProps & React.RefAttributes<HTMLDivElement>>;
|
|
22
|
+
export interface ChatLayoutHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
23
|
+
}
|
|
24
|
+
declare const ChatLayoutHeader: React.ForwardRefExoticComponent<ChatLayoutHeaderProps & React.RefAttributes<HTMLDivElement>>;
|
|
25
|
+
export interface ChatLayoutMainProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
26
|
+
}
|
|
27
|
+
declare const ChatLayoutMain: React.ForwardRefExoticComponent<ChatLayoutMainProps & React.RefAttributes<HTMLDivElement>>;
|
|
28
|
+
export interface ChatLayoutBodyProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
29
|
+
/** Whether to show toaster */
|
|
30
|
+
showToaster?: boolean;
|
|
31
|
+
}
|
|
32
|
+
declare const ChatLayoutBody: React.ForwardRefExoticComponent<ChatLayoutBodyProps & React.RefAttributes<HTMLDivElement>>;
|
|
33
|
+
export interface ChatLayoutMessagesProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
34
|
+
/** Callback when scroll position changes */
|
|
35
|
+
onScrollChange?: (isAtBottom: boolean) => void;
|
|
36
|
+
/** Whether to show scroll to bottom button */
|
|
37
|
+
showScrollToBottom?: boolean;
|
|
38
|
+
}
|
|
39
|
+
declare const ChatLayoutMessages: React.ForwardRefExoticComponent<ChatLayoutMessagesProps & React.RefAttributes<HTMLDivElement>>;
|
|
40
|
+
export interface ChatLayoutFooterProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
41
|
+
}
|
|
42
|
+
declare const ChatLayoutFooter: React.ForwardRefExoticComponent<ChatLayoutFooterProps & React.RefAttributes<HTMLDivElement>>;
|
|
43
|
+
export interface ChatLayoutSidebarProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
44
|
+
}
|
|
45
|
+
declare const ChatLayoutSidebar: React.ForwardRefExoticComponent<ChatLayoutSidebarProps & React.RefAttributes<HTMLDivElement>>;
|
|
46
|
+
export interface ChatLayoutAsideProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
47
|
+
/** Show panel on these breakpoints (default: lg and above) */
|
|
48
|
+
breakpoint?: "md" | "lg" | "xl" | "2xl";
|
|
49
|
+
}
|
|
50
|
+
declare const ChatLayoutAside: React.ForwardRefExoticComponent<ChatLayoutAsideProps & React.RefAttributes<HTMLDivElement>>;
|
|
51
|
+
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, };
|
|
52
|
+
export type { PanelSize, PanelTabType };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ArrowDown } from "lucide-react";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "../lib/utils.js";
|
|
5
|
+
import { Toaster } from "./Sonner.js";
|
|
6
|
+
const ChatLayoutContext = React.createContext(undefined);
|
|
7
|
+
const useChatLayoutContext = () => {
|
|
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;
|
|
13
|
+
};
|
|
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
|
+
});
|
|
27
|
+
ChatLayoutRoot.displayName = "ChatLayout.Root";
|
|
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
|
+
});
|
|
31
|
+
ChatLayoutHeader.displayName = "ChatLayout.Header";
|
|
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
|
+
});
|
|
35
|
+
ChatLayoutMain.displayName = "ChatLayout.Main";
|
|
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
|
+
});
|
|
39
|
+
ChatLayoutBody.displayName = "ChatLayout.Body";
|
|
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
|
+
});
|
|
76
|
+
ChatLayoutMessages.displayName = "ChatLayout.Messages";
|
|
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
|
+
});
|
|
80
|
+
ChatLayoutFooter.displayName = "ChatLayout.Footer";
|
|
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
|
+
});
|
|
87
|
+
ChatLayoutSidebar.displayName = "ChatLayout.Sidebar";
|
|
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-[32rem]", className), ...props, children: children }));
|
|
100
|
+
});
|
|
101
|
+
ChatLayoutAside.displayName = "ChatLayout.Aside";
|
|
102
|
+
/* -------------------------------------------------------------------------------------------------
|
|
103
|
+
* Exports
|
|
104
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
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, };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { TodoItem } from "./TodoListItem.js";
|
|
3
|
+
/**
|
|
4
|
+
* Shared tab content components for both mobile (ChatHeader) and desktop (Panel) views
|
|
5
|
+
* Following component architecture best practices
|
|
6
|
+
*/
|
|
7
|
+
export interface TodoTabContentProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
8
|
+
todos: TodoItem[];
|
|
9
|
+
}
|
|
10
|
+
export declare const TodoTabContent: React.ForwardRefExoticComponent<TodoTabContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
11
|
+
export interface FilesTabContentProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
12
|
+
files?: string[];
|
|
13
|
+
}
|
|
14
|
+
export declare const FilesTabContent: React.ForwardRefExoticComponent<FilesTabContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
15
|
+
export interface DatabaseTabContentProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
16
|
+
data?: unknown;
|
|
17
|
+
}
|
|
18
|
+
export declare const DatabaseTabContent: React.ForwardRefExoticComponent<DatabaseTabContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
export const TodoTabContent = React.forwardRef(({ todos, className, ...props }, ref) => {
|
|
5
|
+
return (_jsxs("div", { ref: ref, className: cn("space-y-4", className), ...props, children: [_jsx("h3", { className: "font-semibold text-lg", children: "Tasks" }), _jsx("div", { className: "space-y-2", children: todos.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "No tasks yet" })) : (todos.map((todo) => (_jsx("div", { className: "text-sm", children: todo.text }, todo.id)))) })] }));
|
|
6
|
+
});
|
|
7
|
+
TodoTabContent.displayName = "TodoTabContent";
|
|
8
|
+
export const FilesTabContent = React.forwardRef(({ files = [], className, ...props }, ref) => {
|
|
9
|
+
return (_jsxs("div", { ref: ref, className: cn("space-y-4", className), ...props, children: [_jsx("h3", { className: "font-semibold text-lg", children: "Files" }), files.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "No files attached" })) : (_jsx("div", { className: "space-y-2", children: files.map((file) => (_jsx("div", { className: "text-sm", children: file }, file))) }))] }));
|
|
10
|
+
});
|
|
11
|
+
FilesTabContent.displayName = "FilesTabContent";
|
|
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
|
+
});
|
|
15
|
+
DatabaseTabContent.displayName = "DatabaseTabContent";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ThemeConfig } from "./ConfigPanel.js";
|
|
2
|
+
interface ChatPreviewProps {
|
|
3
|
+
config: ThemeConfig;
|
|
4
|
+
status: string;
|
|
5
|
+
iframeSrc?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function ChatPreview({ config, status, iframeSrc, }: ChatPreviewProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=ChatPreview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatPreview.d.ts","sourceRoot":"","sources":["../../../src/gui/components/ChatPreview.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,UAAU,gBAAgB;IACxB,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAYD,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,MAAM,EACN,SAA8B,GAC/B,EAAE,gBAAgB,2CA2OlB"}
|