@alpaca-editor/core 1.0.4156 → 1.0.4157

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 (139) hide show
  1. package/dist/config/config.js +26 -56
  2. package/dist/config/config.js.map +1 -1
  3. package/dist/editor/ContextMenu.js +17 -8
  4. package/dist/editor/ContextMenu.js.map +1 -1
  5. package/dist/editor/EditorWarning.js +2 -1
  6. package/dist/editor/EditorWarning.js.map +1 -1
  7. package/dist/editor/FieldListField.js +2 -2
  8. package/dist/editor/FieldListField.js.map +1 -1
  9. package/dist/editor/FieldListFieldWithFallbacks.js +2 -1
  10. package/dist/editor/FieldListFieldWithFallbacks.js.map +1 -1
  11. package/dist/editor/FloatingToolbar.js +3 -2
  12. package/dist/editor/FloatingToolbar.js.map +1 -1
  13. package/dist/editor/ImageEditButton.d.ts +1 -1
  14. package/dist/editor/ImageEditButton.js +2 -2
  15. package/dist/editor/ImageEditButton.js.map +1 -1
  16. package/dist/editor/ImageEditor.js +13 -2
  17. package/dist/editor/ImageEditor.js.map +1 -1
  18. package/dist/editor/PictureEditor.js +18 -33
  19. package/dist/editor/PictureEditor.js.map +1 -1
  20. package/dist/editor/PictureEditorDialog.js +3 -2
  21. package/dist/editor/PictureEditorDialog.js.map +1 -1
  22. package/dist/editor/ai/DancingDots.js +1 -1
  23. package/dist/editor/ai/DancingDots.js.map +1 -1
  24. package/dist/editor/client/AboutDialog.js +2 -2
  25. package/dist/editor/client/AboutDialog.js.map +1 -1
  26. package/dist/editor/client/EditorShell.d.ts +0 -2
  27. package/dist/editor/client/EditorShell.js +0 -2
  28. package/dist/editor/client/EditorShell.js.map +1 -1
  29. package/dist/editor/commands/createVersionCommand.js +1 -1
  30. package/dist/editor/commands/createVersionCommand.js.map +1 -1
  31. package/dist/editor/commands/deleteVersionCommand.js +1 -1
  32. package/dist/editor/commands/deleteVersionCommand.js.map +1 -1
  33. package/dist/editor/commands/undo.js +2 -2
  34. package/dist/editor/commands/undo.js.map +1 -1
  35. package/dist/editor/control-center/Status.js +2 -1
  36. package/dist/editor/control-center/Status.js.map +1 -1
  37. package/dist/editor/control-center/WebSocketMessages.js +3 -2
  38. package/dist/editor/control-center/WebSocketMessages.js.map +1 -1
  39. package/dist/editor/field-types/TreeListEditor.js +5 -3
  40. package/dist/editor/field-types/TreeListEditor.js.map +1 -1
  41. package/dist/editor/media-selector/AiImageSearch.js +0 -1
  42. package/dist/editor/media-selector/AiImageSearch.js.map +1 -1
  43. package/dist/editor/media-selector/UploadZone.js +2 -1
  44. package/dist/editor/media-selector/UploadZone.js.map +1 -1
  45. package/dist/editor/menubar/ActiveUsers.js +2 -1
  46. package/dist/editor/menubar/ActiveUsers.js.map +1 -1
  47. package/dist/editor/menubar/NavButtons.js +3 -2
  48. package/dist/editor/menubar/NavButtons.js.map +1 -1
  49. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +2 -1
  50. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
  51. package/dist/editor/pageModel.d.ts +2 -1
  52. package/dist/editor/reviews/PreviewInfo.js +2 -1
  53. package/dist/editor/reviews/PreviewInfo.js.map +1 -1
  54. package/dist/editor/reviews/Reviews.js +5 -5
  55. package/dist/editor/reviews/Reviews.js.map +1 -1
  56. package/dist/editor/reviews/SuggestedEdit.js +2 -2
  57. package/dist/editor/reviews/SuggestedEdit.js.map +1 -1
  58. package/dist/editor/sidebar/ComponentPalette.js +2 -1
  59. package/dist/editor/sidebar/ComponentPalette.js.map +1 -1
  60. package/dist/editor/sidebar/ComponentTree.js +14 -13
  61. package/dist/editor/sidebar/ComponentTree.js.map +1 -1
  62. package/dist/editor/sidebar/Validation.js +2 -2
  63. package/dist/editor/sidebar/Validation.js.map +1 -1
  64. package/dist/editor/sidebar/Workbox.js.map +1 -1
  65. package/dist/editor/ui/Spinner.js +13 -1
  66. package/dist/editor/ui/Spinner.js.map +1 -1
  67. package/dist/page-wizard/startPageWizardCommand.js +1 -1
  68. package/dist/page-wizard/startPageWizardCommand.js.map +1 -1
  69. package/dist/page-wizard/steps/Components.js +2 -1
  70. package/dist/page-wizard/steps/Components.js.map +1 -1
  71. package/dist/page-wizard/steps/FieldEditor.js +2 -2
  72. package/dist/page-wizard/steps/FieldEditor.js.map +1 -1
  73. package/dist/page-wizard/steps/LayoutStep.js +2 -1
  74. package/dist/page-wizard/steps/LayoutStep.js.map +1 -1
  75. package/dist/revision.d.ts +2 -2
  76. package/dist/revision.js +2 -2
  77. package/dist/splash-screen/NewPage.js +2 -2
  78. package/dist/splash-screen/NewPage.js.map +1 -1
  79. package/dist/splash-screen/OpenPage.js +2 -2
  80. package/dist/splash-screen/OpenPage.js.map +1 -1
  81. package/dist/splash-screen/RecentPages.js +2 -1
  82. package/dist/splash-screen/RecentPages.js.map +1 -1
  83. package/dist/splash-screen/SplashScreen.js +1 -1
  84. package/dist/splash-screen/SplashScreen.js.map +1 -1
  85. package/dist/styles.css +0 -20
  86. package/dist/tour/default-tour.js +9 -8
  87. package/dist/tour/default-tour.js.map +1 -1
  88. package/dist/tour/preview-tour.js +7 -6
  89. package/dist/tour/preview-tour.js.map +1 -1
  90. package/package.json +2 -4
  91. package/src/config/config.tsx +42 -60
  92. package/src/editor/ContextMenu.tsx +17 -8
  93. package/src/editor/EditorWarning.tsx +2 -1
  94. package/src/editor/FieldListField.tsx +2 -1
  95. package/src/editor/FieldListFieldWithFallbacks.tsx +2 -1
  96. package/src/editor/FloatingToolbar.tsx +11 -13
  97. package/src/editor/ImageEditButton.tsx +3 -3
  98. package/src/editor/ImageEditor.tsx +14 -2
  99. package/src/editor/PictureEditor.tsx +40 -50
  100. package/src/editor/PictureEditorDialog.tsx +3 -2
  101. package/src/editor/PublishDialog.ignore +1 -2
  102. package/src/editor/ai/DancingDots.tsx +10 -5
  103. package/src/editor/client/AboutDialog.tsx +7 -2
  104. package/src/editor/client/EditorShell.tsx +0 -2
  105. package/src/editor/commands/createVersionCommand.ts +1 -1
  106. package/src/editor/commands/deleteVersionCommand.ts +1 -1
  107. package/src/editor/commands/undo.ts +2 -2
  108. package/src/editor/control-center/Status.tsx +2 -1
  109. package/src/editor/control-center/WebSocketMessages.tsx +7 -4
  110. package/src/editor/field-types/TreeListEditor.tsx +5 -3
  111. package/src/editor/media-selector/AiImageSearch.tsx +0 -1
  112. package/src/editor/media-selector/UploadZone.tsx +2 -1
  113. package/src/editor/menubar/ActiveUsers.tsx +3 -8
  114. package/src/editor/menubar/NavButtons.tsx +3 -2
  115. package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +1 -1
  116. package/src/editor/pageModel.ts +2 -1
  117. package/src/editor/reviews/PreviewInfo.tsx +7 -8
  118. package/src/editor/reviews/Reviews.tsx +5 -5
  119. package/src/editor/reviews/SuggestedEdit.tsx +4 -3
  120. package/src/editor/sidebar/ComponentPalette.tsx +4 -4
  121. package/src/editor/sidebar/ComponentTree.tsx +26 -12
  122. package/src/editor/sidebar/Validation.tsx +2 -2
  123. package/src/editor/sidebar/Workbox.tsx +3 -3
  124. package/src/editor/ui/Spinner.tsx +17 -3
  125. package/src/page-wizard/startPageWizardCommand.ts +1 -1
  126. package/src/page-wizard/steps/Components.tsx +2 -1
  127. package/src/page-wizard/steps/FieldEditor.tsx +5 -8
  128. package/src/page-wizard/steps/LayoutStep.tsx +2 -1
  129. package/src/revision.ts +2 -2
  130. package/src/splash-screen/NewPage.tsx +2 -2
  131. package/src/splash-screen/OpenPage.tsx +2 -2
  132. package/src/splash-screen/RecentPages.tsx +3 -2
  133. package/src/splash-screen/SplashScreen.tsx +4 -4
  134. package/src/tour/default-tour.tsx +9 -8
  135. package/src/tour/preview-tour.tsx +7 -6
  136. package/dist/editor/Terminal.d.ts +0 -24
  137. package/dist/editor/Terminal.js +0 -158
  138. package/dist/editor/Terminal.js.map +0 -1
  139. package/src/editor/Terminal.tsx +0 -286
@@ -1,158 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { forwardRef, useEffect, useRef, useState, useImperativeHandle, } from "react";
3
- import { Textarea } from "../components/ui/textarea";
4
- import { cn } from "../lib/utils";
5
- import { SimpleIconButton } from "./ui/SimpleIconButton";
6
- import { Trash2, Send } from "lucide-react";
7
- import { TerminalService } from "primereact/terminalservice";
8
- export const Terminal = forwardRef((props, ref) => {
9
- const { commandHandler, prompt, setPrompt, placeholder, onReset, toolbar, statusbar, rightbar, submitOverride, infobar, disabled, className, initialMessages, } = props;
10
- const [response, setResponse] = useState();
11
- const [messages, setMessages] = useState([]);
12
- const bottomRef = useRef(null);
13
- const messageRef = useRef(messages);
14
- const inputRef = useRef(null);
15
- const [promptHistory, setPromptHistory] = useState(() => {
16
- if (typeof window !== "undefined") {
17
- return JSON.parse(localStorage.getItem("editor.ai.promptHistory") || "[]");
18
- }
19
- return [];
20
- });
21
- const [currentHistoryIndex, setCurrentHistoryIndex] = useState(-1);
22
- useEffect(() => {
23
- localStorage.setItem("editor.ai.promptHistory", JSON.stringify(promptHistory));
24
- }, [promptHistory]);
25
- useEffect(() => {
26
- if (inputRef.current) {
27
- inputRef.current.focus();
28
- }
29
- }, []);
30
- useEffect(() => {
31
- messageRef.current = messages;
32
- }, [messages]);
33
- // Allow external responses via TerminalService (e.g., reconnection streaming)
34
- useEffect(() => {
35
- const responseHandler = (payload) => {
36
- const { text, finished } = payload || {};
37
- const isFinished = typeof finished === "boolean" ? finished : payload?.type === "response";
38
- if (!isFinished)
39
- setResponse(text);
40
- else {
41
- setResponse(undefined);
42
- setMessages([...messageRef.current, { type: "response", text }]);
43
- }
44
- };
45
- // @ts-ignore
46
- TerminalService.on("response", responseHandler);
47
- return () => {
48
- // @ts-ignore
49
- TerminalService.off("response", responseHandler);
50
- };
51
- }, []);
52
- // Set initial messages if provided
53
- useEffect(() => {
54
- if (initialMessages &&
55
- initialMessages.length > 0 &&
56
- messages.length === 0) {
57
- setMessages(initialMessages);
58
- }
59
- }, [initialMessages]);
60
- const callback = (text, finished) => {
61
- if (!finished)
62
- setResponse(text);
63
- else {
64
- setResponse(undefined);
65
- setMessages([...messageRef.current, { type: "response", text }]);
66
- }
67
- };
68
- const handleKeyPress = (e) => {
69
- if (e.key === "Enter" && !e.shiftKey) {
70
- e.preventDefault();
71
- submit();
72
- }
73
- if (e.key === "ArrowUp") {
74
- // Only navigate history if prompt is empty or we're already navigating history
75
- const canNavigateHistory = prompt.trim().length === 0 || currentHistoryIndex !== -1;
76
- if (canNavigateHistory) {
77
- e.preventDefault();
78
- if (promptHistory.length > 0) {
79
- const newIndex = currentHistoryIndex < promptHistory.length - 1
80
- ? currentHistoryIndex + 1
81
- : currentHistoryIndex;
82
- setCurrentHistoryIndex(newIndex);
83
- const historicalPrompt = promptHistory[newIndex];
84
- if (inputRef.current && historicalPrompt) {
85
- setPrompt(historicalPrompt);
86
- setTimeout(() => {
87
- inputRef.current.selectionStart = historicalPrompt.length;
88
- inputRef.current.selectionEnd = historicalPrompt.length;
89
- }, 0);
90
- }
91
- }
92
- }
93
- }
94
- if (e.key === "ArrowDown" && currentHistoryIndex >= 0) {
95
- e.preventDefault();
96
- const newIndex = currentHistoryIndex - 1;
97
- setCurrentHistoryIndex(newIndex);
98
- const historicalPrompt = newIndex >= 0 ? promptHistory[newIndex] || "" : "";
99
- setPrompt(historicalPrompt);
100
- if (inputRef.current) {
101
- setTimeout(() => {
102
- inputRef.current.selectionStart = historicalPrompt.length;
103
- inputRef.current.selectionEnd = historicalPrompt.length;
104
- }, 0);
105
- }
106
- }
107
- };
108
- useEffect(() => {
109
- // Scroll to bottom every time messages or response changes.
110
- bottomRef.current?.scrollIntoView({ behavior: "smooth" });
111
- }, [messages, response]);
112
- const responseBoxClasses = "text-xs self-stretch text-dark p-2 rounded border border-theme-secondary bg-theme-secondary-light min-h-8 flex flex-col justify-end";
113
- const getClasses = (m) => {
114
- if (m.type === "response")
115
- return responseBoxClasses;
116
- return "text-xs text-dark bg-indigo-100 border border-indigo-300 p-2 rounded prompt";
117
- };
118
- // Expose the submit function via the ref.
119
- const submit = () => {
120
- if (prompt.trim()) {
121
- setPromptHistory((prev) => [
122
- prompt,
123
- ...prev.filter((p) => p !== prompt).slice(0, 9),
124
- ]);
125
- setCurrentHistoryIndex(-1);
126
- }
127
- setMessages([...messages, { type: "command", text: prompt }]);
128
- setPrompt("");
129
- setResponse("");
130
- commandHandler(prompt, callback);
131
- };
132
- useImperativeHandle(ref, () => ({
133
- submit,
134
- focusPrompt: () => {
135
- if (inputRef.current) {
136
- inputRef.current.focus();
137
- const value = inputRef.current.value || "";
138
- try {
139
- inputRef.current.selectionStart = value.length;
140
- inputRef.current.selectionEnd = value.length;
141
- }
142
- catch { }
143
- }
144
- },
145
- }));
146
- return (_jsxs("div", { className: cn("flex h-full flex-col", className), children: [_jsxs("div", { className: "flex items-center justify-between gap-2 border-b border-gray-200 p-1 text-xs", children: [_jsx(SimpleIconButton, { onClick: () => {
147
- setMessages([]);
148
- onReset();
149
- }, icon: _jsx(Trash2, { size: 16, strokeWidth: 1 }), label: "Clear terminal" }), toolbar] }), _jsx("div", { className: "flex-1 overflow-x-hidden overflow-y-auto p-2", children: _jsxs("div", { className: "flex flex-col items-end gap-3 select-text", children: [messages.map((m, i) => (_jsx("div", { className: getClasses(m), children: m.text }, i))), response != null && (_jsxs("div", { className: responseBoxClasses, children: [_jsx("div", { className: "flex text-xs", children: response }), _jsxs("div", { className: "mr-4 flex items-center justify-end space-x-1 text-xs text-gray-400", children: [_jsx("div", { className: "h-1 w-1 animate-bounce rounded-full bg-gray-400 [animation-delay:-0.3s]" }), _jsx("div", { className: "h-1 w-1 animate-bounce rounded-full bg-gray-400 [animation-delay:-0.15s]" }), _jsx("div", { className: "h-1 w-1 animate-bounce rounded-full bg-gray-400" })] })] })), _jsx("div", { ref: bottomRef })] }) }), _jsxs("div", { className: "flex flex-col p-1 pb-0", children: [infobar, _jsx(Textarea, { ref: inputRef, value: prompt, className: "flex-1 resize-none self-stretch rounded border border-gray-300 text-xs", onKeyDown: handleKeyPress, onChange: (e) => {
150
- setPrompt(e.target.value);
151
- // Reset history index when user starts typing
152
- if (currentHistoryIndex !== -1) {
153
- setCurrentHistoryIndex(-1);
154
- }
155
- }, rows: 4, cols: 30, disabled: disabled, placeholder: placeholder ??
156
- "Type your message... (Enter to send, Shift+Enter for new line)" }), _jsxs("div", { className: "flex items-center justify-between py-1", children: [statusbar, _jsxs("div", { className: "flex items-center gap-1", children: [rightbar, submitOverride ?? (_jsx(SimpleIconButton, { icon: _jsx(Send, { size: 16, strokeWidth: 1 }), className: "tour-send-button", onClick: submit, disabled: prompt.trim().length === 0, label: "Send" }))] })] })] })] }));
157
- });
158
- //# sourceMappingURL=Terminal.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Terminal.js","sourceRoot":"","sources":["../../src/editor/Terminal.tsx"],"names":[],"mappings":"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"}
@@ -1,286 +0,0 @@
1
- import React, {
2
- forwardRef,
3
- useEffect,
4
- useRef,
5
- useState,
6
- useImperativeHandle,
7
- } from "react";
8
- import { Textarea } from "../components/ui/textarea";
9
- import { cn } from "../lib/utils";
10
- import { SimpleIconButton } from "./ui/SimpleIconButton";
11
- import { Trash2, Send } from "lucide-react";
12
- import { TerminalService } from "primereact/terminalservice";
13
-
14
- type Message = {
15
- text: React.ReactNode;
16
- type: "command" | "response";
17
- };
18
-
19
- export const Terminal = forwardRef<
20
- { submit: () => void; focusPrompt: () => void },
21
- {
22
- commandHandler: (
23
- text: string,
24
- callback: (text: React.ReactNode, finished: boolean) => void,
25
- ) => void;
26
- prompt: string;
27
- setPrompt: (text: string) => void;
28
- placeholder?: string;
29
- onReset: () => void;
30
- toolbar?: React.ReactNode;
31
- statusbar?: React.ReactNode;
32
- rightbar?: React.ReactNode;
33
- submitOverride?: React.ReactNode;
34
- infobar?: React.ReactNode;
35
- disabled?: boolean;
36
- className?: string;
37
- initialMessages?: Message[];
38
- }
39
- >((props, ref) => {
40
- const {
41
- commandHandler,
42
- prompt,
43
- setPrompt,
44
- placeholder,
45
- onReset,
46
- toolbar,
47
- statusbar,
48
- rightbar,
49
- submitOverride,
50
- infobar,
51
- disabled,
52
- className,
53
- initialMessages,
54
- } = props;
55
-
56
- const [response, setResponse] = useState<React.ReactNode>();
57
- const [messages, setMessages] = useState<Message[]>([]);
58
- const bottomRef = useRef<HTMLDivElement | null>(null);
59
- const messageRef = useRef(messages);
60
- const inputRef = useRef<HTMLTextAreaElement>(null);
61
- const [promptHistory, setPromptHistory] = useState<string[]>(() => {
62
- if (typeof window !== "undefined") {
63
- return JSON.parse(
64
- localStorage.getItem("editor.ai.promptHistory") || "[]",
65
- );
66
- }
67
- return [];
68
- });
69
- const [currentHistoryIndex, setCurrentHistoryIndex] = useState<number>(-1);
70
-
71
- useEffect(() => {
72
- localStorage.setItem(
73
- "editor.ai.promptHistory",
74
- JSON.stringify(promptHistory),
75
- );
76
- }, [promptHistory]);
77
-
78
- useEffect(() => {
79
- if (inputRef.current) {
80
- inputRef.current.focus();
81
- }
82
- }, []);
83
-
84
- useEffect(() => {
85
- messageRef.current = messages;
86
- }, [messages]);
87
-
88
- // Allow external responses via TerminalService (e.g., reconnection streaming)
89
- useEffect(() => {
90
- const responseHandler = (payload: any) => {
91
- const { text, finished } = payload || {};
92
- const isFinished =
93
- typeof finished === "boolean" ? finished : payload?.type === "response";
94
- if (!isFinished) setResponse(text);
95
- else {
96
- setResponse(undefined);
97
- setMessages([...messageRef.current, { type: "response", text }]);
98
- }
99
- };
100
- // @ts-ignore
101
- TerminalService.on("response", responseHandler);
102
- return () => {
103
- // @ts-ignore
104
- TerminalService.off("response", responseHandler);
105
- };
106
- }, []);
107
-
108
- // Set initial messages if provided
109
- useEffect(() => {
110
- if (
111
- initialMessages &&
112
- initialMessages.length > 0 &&
113
- messages.length === 0
114
- ) {
115
- setMessages(initialMessages);
116
- }
117
- }, [initialMessages]);
118
-
119
- const callback = (text: React.ReactNode, finished: boolean) => {
120
- if (!finished) setResponse(text);
121
- else {
122
- setResponse(undefined);
123
- setMessages([...messageRef.current, { type: "response", text }]);
124
- }
125
- };
126
-
127
- const handleKeyPress = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
128
- if (e.key === "Enter" && !e.shiftKey) {
129
- e.preventDefault();
130
- submit();
131
- }
132
- if (e.key === "ArrowUp") {
133
- // Only navigate history if prompt is empty or we're already navigating history
134
- const canNavigateHistory =
135
- prompt.trim().length === 0 || currentHistoryIndex !== -1;
136
- if (canNavigateHistory) {
137
- e.preventDefault();
138
- if (promptHistory.length > 0) {
139
- const newIndex =
140
- currentHistoryIndex < promptHistory.length - 1
141
- ? currentHistoryIndex + 1
142
- : currentHistoryIndex;
143
- setCurrentHistoryIndex(newIndex);
144
- const historicalPrompt = promptHistory[newIndex];
145
- if (inputRef.current && historicalPrompt) {
146
- setPrompt(historicalPrompt);
147
- setTimeout(() => {
148
- inputRef.current!.selectionStart = historicalPrompt.length;
149
- inputRef.current!.selectionEnd = historicalPrompt.length;
150
- }, 0);
151
- }
152
- }
153
- }
154
- }
155
- if (e.key === "ArrowDown" && currentHistoryIndex >= 0) {
156
- e.preventDefault();
157
- const newIndex = currentHistoryIndex - 1;
158
- setCurrentHistoryIndex(newIndex);
159
- const historicalPrompt =
160
- newIndex >= 0 ? promptHistory[newIndex] || "" : "";
161
- setPrompt(historicalPrompt);
162
- if (inputRef.current) {
163
- setTimeout(() => {
164
- inputRef.current!.selectionStart = historicalPrompt.length;
165
- inputRef.current!.selectionEnd = historicalPrompt.length;
166
- }, 0);
167
- }
168
- }
169
- };
170
-
171
- useEffect(() => {
172
- // Scroll to bottom every time messages or response changes.
173
- bottomRef.current?.scrollIntoView({ behavior: "smooth" });
174
- }, [messages, response]);
175
-
176
- const responseBoxClasses =
177
- "text-xs self-stretch text-dark p-2 rounded border border-theme-secondary bg-theme-secondary-light min-h-8 flex flex-col justify-end";
178
- const getClasses = (m: Message) => {
179
- if (m.type === "response") return responseBoxClasses;
180
- return "text-xs text-dark bg-indigo-100 border border-indigo-300 p-2 rounded prompt";
181
- };
182
-
183
- // Expose the submit function via the ref.
184
- const submit = () => {
185
- if (prompt.trim()) {
186
- setPromptHistory((prev) => [
187
- prompt,
188
- ...prev.filter((p) => p !== prompt).slice(0, 9),
189
- ]);
190
- setCurrentHistoryIndex(-1);
191
- }
192
- setMessages([...messages, { type: "command", text: prompt }]);
193
- setPrompt("");
194
- setResponse("");
195
- commandHandler(prompt, callback);
196
- };
197
-
198
- useImperativeHandle(ref, () => ({
199
- submit,
200
- focusPrompt: () => {
201
- if (inputRef.current) {
202
- inputRef.current.focus();
203
- const value = inputRef.current.value || "";
204
- try {
205
- inputRef.current.selectionStart = value.length;
206
- inputRef.current.selectionEnd = value.length;
207
- } catch {}
208
- }
209
- },
210
- }));
211
-
212
- return (
213
- <div className={cn("flex h-full flex-col", className)}>
214
- <div className="flex items-center justify-between gap-2 border-b border-gray-200 p-1 text-xs">
215
- <SimpleIconButton
216
- onClick={() => {
217
- setMessages([]);
218
- onReset();
219
- }}
220
- icon={<Trash2 size={16} strokeWidth={1} />}
221
- label="Clear terminal"
222
- />
223
- {toolbar}
224
- </div>
225
- <div className="flex-1 overflow-x-hidden overflow-y-auto p-2">
226
- <div className="flex flex-col items-end gap-3 select-text">
227
- {messages.map((m, i) => (
228
- <div key={i} className={getClasses(m)}>
229
- {m.text}
230
- </div>
231
- ))}
232
-
233
- {response != null && (
234
- <div className={responseBoxClasses}>
235
- <div className="flex text-xs">{response}</div>
236
- <div className="mr-4 flex items-center justify-end space-x-1 text-xs text-gray-400">
237
- <div className="h-1 w-1 animate-bounce rounded-full bg-gray-400 [animation-delay:-0.3s]"></div>
238
- <div className="h-1 w-1 animate-bounce rounded-full bg-gray-400 [animation-delay:-0.15s]"></div>
239
- <div className="h-1 w-1 animate-bounce rounded-full bg-gray-400"></div>
240
- </div>
241
- </div>
242
- )}
243
- <div ref={bottomRef} />
244
- </div>
245
- </div>
246
- <div className="flex flex-col p-1 pb-0">
247
- {infobar}
248
- <Textarea
249
- ref={inputRef}
250
- value={prompt}
251
- className="flex-1 resize-none self-stretch rounded border border-gray-300 text-xs"
252
- onKeyDown={handleKeyPress}
253
- onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => {
254
- setPrompt(e.target.value);
255
- // Reset history index when user starts typing
256
- if (currentHistoryIndex !== -1) {
257
- setCurrentHistoryIndex(-1);
258
- }
259
- }}
260
- rows={4}
261
- cols={30}
262
- disabled={disabled}
263
- placeholder={
264
- placeholder ??
265
- "Type your message... (Enter to send, Shift+Enter for new line)"
266
- }
267
- />
268
- <div className="flex items-center justify-between py-1">
269
- {statusbar}
270
- <div className="flex items-center gap-1">
271
- {rightbar}
272
- {submitOverride ?? (
273
- <SimpleIconButton
274
- icon={<Send size={16} strokeWidth={1} />}
275
- className="tour-send-button"
276
- onClick={submit}
277
- disabled={prompt.trim().length === 0}
278
- label="Send"
279
- />
280
- )}
281
- </div>
282
- </div>
283
- </div>
284
- </div>
285
- );
286
- });