@townco/ui 0.1.0 → 0.1.6
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/dist/core/hooks/use-chat-input.d.ts +17 -17
- package/dist/core/hooks/use-chat-input.js +64 -55
- package/dist/core/hooks/use-chat-messages.d.ts +11 -11
- package/dist/core/hooks/use-chat-messages.js +121 -114
- package/dist/core/hooks/use-chat-session.d.ts +5 -5
- package/dist/core/hooks/use-chat-session.js +78 -80
- package/dist/core/hooks/use-media-query.d.ts +5 -5
- package/dist/core/hooks/use-media-query.js +38 -38
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/schemas/chat.d.ts +83 -56
- package/dist/core/schemas/chat.js +27 -25
- package/dist/core/store/chat-store.d.ts +28 -22
- package/dist/core/store/chat-store.js +59 -50
- package/dist/gui/components/Button.d.ts +23 -7
- package/dist/gui/components/Button.js +40 -27
- package/dist/gui/components/Card.d.ts +26 -7
- package/dist/gui/components/Card.js +54 -8
- package/dist/gui/components/ChatHeader.d.ts +58 -31
- package/dist/gui/components/ChatHeader.js +171 -66
- package/dist/gui/components/ChatInput.d.ts +58 -36
- package/dist/gui/components/ChatInput.js +191 -121
- package/dist/gui/components/ChatInterface.d.ts +9 -6
- package/dist/gui/components/ChatInterface.js +162 -90
- package/dist/gui/components/ChatLayout.d.ts +71 -41
- package/dist/gui/components/ChatLayout.js +214 -87
- package/dist/gui/components/ChatPanelTabContent.d.ts +18 -9
- package/dist/gui/components/ChatPanelTabContent.js +88 -10
- package/dist/gui/components/ChatPreview.d.ts +9 -6
- package/dist/gui/components/ChatPreview.js +212 -162
- package/dist/gui/components/ChatSecondaryPanel.d.ts +14 -11
- package/dist/gui/components/ChatSecondaryPanel.js +115 -38
- package/dist/gui/components/ChatSidebar.d.ts +26 -13
- package/dist/gui/components/ChatSidebar.js +48 -14
- package/dist/gui/components/ChatStatus.d.ts +4 -2
- package/dist/gui/components/ChatStatus.js +45 -34
- package/dist/gui/components/ChatView.d.ts +5 -3
- package/dist/gui/components/ChatView.js +38 -9
- package/dist/gui/components/ConfigPanel.d.ts +16 -12
- package/dist/gui/components/ConfigPanel.js +218 -41
- package/dist/gui/components/Conversation.d.ts +17 -14
- package/dist/gui/components/Conversation.js +143 -83
- package/dist/gui/components/Dialog.d.ts +57 -11
- package/dist/gui/components/Dialog.js +84 -8
- package/dist/gui/components/DropdownMenu.d.ts +101 -20
- package/dist/gui/components/DropdownMenu.js +161 -14
- package/dist/gui/components/HeightTransition.d.ts +12 -7
- package/dist/gui/components/HeightTransition.js +88 -77
- package/dist/gui/components/Input.d.ts +13 -6
- package/dist/gui/components/Input.js +27 -16
- package/dist/gui/components/InputBox.d.ts +19 -12
- package/dist/gui/components/InputBox.js +86 -14
- package/dist/gui/components/Label.d.ts +7 -1
- package/dist/gui/components/Label.js +12 -2
- package/dist/gui/components/MarkdownRenderer.d.ts +6 -4
- package/dist/gui/components/MarkdownRenderer.js +178 -81
- package/dist/gui/components/Message.d.ts +25 -18
- package/dist/gui/components/Message.js +44 -23
- package/dist/gui/components/MessageContent.d.ts +29 -22
- package/dist/gui/components/MessageContent.js +157 -85
- package/dist/gui/components/PlaygroundLayout.d.ts +9 -5
- package/dist/gui/components/PlaygroundLayout.js +43 -12
- package/dist/gui/components/Reasoning.d.ts +30 -24
- package/dist/gui/components/Reasoning.js +187 -60
- package/dist/gui/components/Response.d.ts +11 -9
- package/dist/gui/components/Response.js +229 -90
- package/dist/gui/components/Select.d.ts +69 -10
- package/dist/gui/components/Select.js +118 -12
- package/dist/gui/components/Sonner.d.ts +3 -1
- package/dist/gui/components/Sonner.js +29 -18
- package/dist/gui/components/StatusBar.d.ts +9 -5
- package/dist/gui/components/StatusBar.js +56 -9
- package/dist/gui/components/Tabs.d.ts +24 -4
- package/dist/gui/components/Tabs.js +32 -4
- package/dist/gui/components/Task.d.ts +28 -24
- package/dist/gui/components/Task.js +164 -31
- package/dist/gui/components/Textarea.d.ts +15 -7
- package/dist/gui/components/Textarea.js +63 -46
- package/dist/gui/components/ThinkingBlock.d.ts +20 -10
- package/dist/gui/components/ThinkingBlock.js +134 -35
- package/dist/gui/components/TodoList.d.ts +12 -10
- package/dist/gui/components/TodoList.js +22 -7
- package/dist/gui/components/TodoListItem.d.ts +9 -6
- package/dist/gui/components/TodoListItem.js +18 -4
- package/dist/gui/components/index.d.ts +59 -8
- package/dist/gui/components/index.js +42 -8
- package/dist/gui/lib/utils.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.test.js +0 -1
- package/dist/sdk/client/acp-client.d.ts +88 -76
- package/dist/sdk/client/acp-client.js +215 -217
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +1 -1
- package/dist/sdk/schemas/agent.d.ts +111 -64
- package/dist/sdk/schemas/agent.js +24 -24
- package/dist/sdk/schemas/message.d.ts +245 -147
- package/dist/sdk/schemas/message.js +40 -40
- package/dist/sdk/schemas/session.d.ts +219 -135
- package/dist/sdk/schemas/session.js +27 -27
- package/dist/sdk/transports/http.d.ts +55 -55
- package/dist/sdk/transports/http.js +472 -469
- package/dist/sdk/transports/stdio.d.ts +20 -20
- package/dist/sdk/transports/stdio.js +289 -286
- package/dist/sdk/transports/types.d.ts +42 -42
- package/dist/sdk/transports/websocket.d.ts +12 -12
- package/dist/sdk/transports/websocket.js +52 -46
- package/dist/tui/components/ChatView.d.ts +4 -2
- package/dist/tui/components/ChatView.js +51 -18
- package/dist/tui/components/GameOfLife.js +64 -35
- package/dist/tui/components/InputBox.d.ts +18 -11
- package/dist/tui/components/InputBox.js +70 -10
- package/dist/tui/components/MessageList.d.ts +4 -2
- package/dist/tui/components/MessageList.js +37 -10
- package/dist/tui/components/MultiSelect.d.ts +15 -9
- package/dist/tui/components/MultiSelect.js +116 -69
- package/dist/tui/components/ReadlineInput.d.ts +12 -6
- package/dist/tui/components/ReadlineInput.js +252 -237
- package/dist/tui/components/SingleSelect.d.ts +15 -9
- package/dist/tui/components/SingleSelect.js +84 -43
- package/dist/tui/components/StatusBar.d.ts +11 -6
- package/dist/tui/components/StatusBar.js +102 -67
- package/dist/tui/index.d.ts +1 -1
- package/dist/tui/index.js +1 -1
- package/package.json +2 -3
|
@@ -1,240 +1,255 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
1
|
import { Text, useInput } from "ink";
|
|
3
2
|
import React, { useState } from "react";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
3
|
+
import {
|
|
4
|
+
Fragment as _Fragment,
|
|
5
|
+
jsx as _jsx,
|
|
6
|
+
jsxs as _jsxs,
|
|
7
|
+
} from "react/jsx-runtime";
|
|
8
|
+
export function ReadlineInput({
|
|
9
|
+
value,
|
|
10
|
+
onChange,
|
|
11
|
+
onSubmit,
|
|
12
|
+
onEscape,
|
|
13
|
+
placeholder = "",
|
|
14
|
+
}) {
|
|
15
|
+
const [cursorOffset, setCursorOffset] = useState(0);
|
|
16
|
+
useInput((input, key) => {
|
|
17
|
+
// Handle Esc: Call escape handler
|
|
18
|
+
if (key.escape) {
|
|
19
|
+
if (onEscape) {
|
|
20
|
+
onEscape();
|
|
21
|
+
}
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// Handle special keys
|
|
25
|
+
if (key.return) {
|
|
26
|
+
const cursorPos = value.length + cursorOffset;
|
|
27
|
+
// Shift+Enter: Insert backslash and newline
|
|
28
|
+
if (key.shift) {
|
|
29
|
+
const newValue = `${value.slice(0, cursorPos)}\\\n${value.slice(cursorPos)}`;
|
|
30
|
+
onChange(newValue);
|
|
31
|
+
if (cursorOffset < 0) {
|
|
32
|
+
setCursorOffset(cursorOffset - 2);
|
|
33
|
+
}
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// Check if cursor is at end and last character is backslash (line continuation)
|
|
37
|
+
if (cursorPos === value.length && value.endsWith("\\")) {
|
|
38
|
+
// Remove backslash and add newline (line continuation)
|
|
39
|
+
const newValue = `${value.slice(0, -1)}\n`;
|
|
40
|
+
onChange(newValue);
|
|
41
|
+
setCursorOffset(0); // Move cursor to end
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// Alt+Enter adds a newline, Enter submits
|
|
45
|
+
if (key.meta) {
|
|
46
|
+
const newValue = `${value.slice(0, cursorPos)}\n${value.slice(cursorPos)}`;
|
|
47
|
+
onChange(newValue);
|
|
48
|
+
if (cursorOffset < 0) {
|
|
49
|
+
setCursorOffset(cursorOffset - 1);
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
onSubmit();
|
|
53
|
+
}
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (key.ctrl) {
|
|
57
|
+
// Ctrl+A: Move to beginning of line
|
|
58
|
+
if (input === "a") {
|
|
59
|
+
setCursorOffset(-value.length);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// Ctrl+E: Move to end of line
|
|
63
|
+
if (input === "e") {
|
|
64
|
+
setCursorOffset(0);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Ctrl+W: Delete word backward
|
|
68
|
+
if (input === "w") {
|
|
69
|
+
const cursorPos = value.length + cursorOffset;
|
|
70
|
+
const before = value.slice(0, cursorPos);
|
|
71
|
+
const after = value.slice(cursorPos);
|
|
72
|
+
// Find the start of the word to delete
|
|
73
|
+
const match = before.match(/\s*\S*$/);
|
|
74
|
+
if (match) {
|
|
75
|
+
const newBefore = before.slice(0, -match[0].length);
|
|
76
|
+
onChange(newBefore + after);
|
|
77
|
+
setCursorOffset(-after.length);
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// Ctrl+U: Delete from cursor to beginning of line
|
|
82
|
+
if (input === "u") {
|
|
83
|
+
const cursorPos = value.length + cursorOffset;
|
|
84
|
+
onChange(value.slice(cursorPos));
|
|
85
|
+
setCursorOffset(-value.slice(cursorPos).length);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// Ctrl+K: Delete from cursor to end of line
|
|
89
|
+
if (input === "k") {
|
|
90
|
+
const cursorPos = value.length + cursorOffset;
|
|
91
|
+
onChange(value.slice(0, cursorPos));
|
|
92
|
+
setCursorOffset(0);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
// Ctrl+D: Delete character forward
|
|
96
|
+
if (input === "d") {
|
|
97
|
+
const cursorPos = value.length + cursorOffset;
|
|
98
|
+
if (cursorPos < value.length) {
|
|
99
|
+
onChange(value.slice(0, cursorPos) + value.slice(cursorPos + 1));
|
|
100
|
+
}
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
// Ctrl+B: Move backward one character
|
|
104
|
+
if (input === "b") {
|
|
105
|
+
const cursorPos = value.length + cursorOffset;
|
|
106
|
+
if (cursorPos > 0) {
|
|
107
|
+
setCursorOffset(cursorOffset - 1);
|
|
108
|
+
}
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
// Ctrl+F: Move forward one character
|
|
112
|
+
if (input === "f") {
|
|
113
|
+
const cursorPos = value.length + cursorOffset;
|
|
114
|
+
if (cursorPos < value.length) {
|
|
115
|
+
setCursorOffset(cursorOffset + 1);
|
|
116
|
+
}
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Handle backspace
|
|
121
|
+
if (key.backspace || key.delete) {
|
|
122
|
+
const cursorPos = value.length + cursorOffset;
|
|
123
|
+
if (cursorPos > 0) {
|
|
124
|
+
onChange(value.slice(0, cursorPos - 1) + value.slice(cursorPos));
|
|
125
|
+
if (cursorOffset < 0) {
|
|
126
|
+
setCursorOffset(cursorOffset + 1);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
// Handle left/right arrow keys
|
|
132
|
+
if (key.leftArrow) {
|
|
133
|
+
const cursorPos = value.length + cursorOffset;
|
|
134
|
+
if (cursorPos > 0) {
|
|
135
|
+
setCursorOffset(cursorOffset - 1);
|
|
136
|
+
}
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (key.rightArrow) {
|
|
140
|
+
const cursorPos = value.length + cursorOffset;
|
|
141
|
+
if (cursorPos < value.length) {
|
|
142
|
+
setCursorOffset(cursorOffset + 1);
|
|
143
|
+
}
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
// Handle up/down arrow keys for multi-line navigation
|
|
147
|
+
if (key.upArrow) {
|
|
148
|
+
const cursorPos = value.length + cursorOffset;
|
|
149
|
+
const lines = value.split("\n");
|
|
150
|
+
// Find which line we're on and our position within it
|
|
151
|
+
let currentLineIndex = 0;
|
|
152
|
+
let charCount = 0;
|
|
153
|
+
let posInLine = cursorPos;
|
|
154
|
+
for (let i = 0; i < lines.length; i++) {
|
|
155
|
+
const line = lines[i];
|
|
156
|
+
if (!line) continue;
|
|
157
|
+
const lineLength = line.length + (i < lines.length - 1 ? 1 : 0); // +1 for \n
|
|
158
|
+
if (charCount + lineLength > cursorPos || i === lines.length - 1) {
|
|
159
|
+
currentLineIndex = i;
|
|
160
|
+
posInLine = cursorPos - charCount;
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
charCount += lineLength;
|
|
164
|
+
}
|
|
165
|
+
// Move to previous line if possible
|
|
166
|
+
if (currentLineIndex > 0) {
|
|
167
|
+
const prevLine = lines[currentLineIndex - 1];
|
|
168
|
+
const currentLine = lines[currentLineIndex];
|
|
169
|
+
if (prevLine && currentLine) {
|
|
170
|
+
const prevLineStart = charCount - currentLine.length - 1;
|
|
171
|
+
const targetPos = Math.min(posInLine, prevLine.length);
|
|
172
|
+
const newCursorPos = prevLineStart + targetPos;
|
|
173
|
+
setCursorOffset(newCursorPos - value.length);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (key.downArrow) {
|
|
179
|
+
const cursorPos = value.length + cursorOffset;
|
|
180
|
+
const lines = value.split("\n");
|
|
181
|
+
// Find which line we're on and our position within it
|
|
182
|
+
let currentLineIndex = 0;
|
|
183
|
+
let charCount = 0;
|
|
184
|
+
let posInLine = cursorPos;
|
|
185
|
+
for (let i = 0; i < lines.length; i++) {
|
|
186
|
+
const line = lines[i];
|
|
187
|
+
if (!line) continue;
|
|
188
|
+
const lineLength = line.length + (i < lines.length - 1 ? 1 : 0); // +1 for \n
|
|
189
|
+
if (charCount + lineLength > cursorPos || i === lines.length - 1) {
|
|
190
|
+
currentLineIndex = i;
|
|
191
|
+
posInLine = cursorPos - charCount;
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
charCount += lineLength;
|
|
195
|
+
}
|
|
196
|
+
// Move to next line if possible
|
|
197
|
+
if (currentLineIndex < lines.length - 1) {
|
|
198
|
+
const nextLine = lines[currentLineIndex + 1];
|
|
199
|
+
const currentLine = lines[currentLineIndex];
|
|
200
|
+
if (nextLine && currentLine) {
|
|
201
|
+
const nextLineStart = charCount + currentLine.length + 1;
|
|
202
|
+
const targetPos = Math.min(posInLine, nextLine.length);
|
|
203
|
+
const newCursorPos = nextLineStart + targetPos;
|
|
204
|
+
setCursorOffset(newCursorPos - value.length);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
// Regular character input and paste detection
|
|
210
|
+
// Ink automatically detects paste and sends the whole string at once
|
|
211
|
+
if (!key.ctrl && !key.meta && input.length > 0) {
|
|
212
|
+
const cursorPos = value.length + cursorOffset;
|
|
213
|
+
// Check if this is a paste with more than 3 lines
|
|
214
|
+
let contentToInsert = input;
|
|
215
|
+
if (input.length > 1) {
|
|
216
|
+
// Pasted content (more than 1 char at once)
|
|
217
|
+
const lines = input.split("\n");
|
|
218
|
+
if (lines.length > 3) {
|
|
219
|
+
contentToInsert = `[Pasted +${lines.length} lines]`;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const newValue =
|
|
223
|
+
value.slice(0, cursorPos) + contentToInsert + value.slice(cursorPos);
|
|
224
|
+
onChange(newValue);
|
|
225
|
+
// Keep cursor at the same relative position
|
|
226
|
+
if (cursorOffset < 0) {
|
|
227
|
+
setCursorOffset(cursorOffset - contentToInsert.length);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
// Reset cursor when value changes externally (e.g., after submit)
|
|
232
|
+
React.useEffect(() => {
|
|
233
|
+
if (value.length === 0) {
|
|
234
|
+
setCursorOffset(0);
|
|
235
|
+
}
|
|
236
|
+
}, [value]);
|
|
237
|
+
// Display the input with cursor
|
|
238
|
+
const cursorPos = value.length + cursorOffset;
|
|
239
|
+
// Show placeholder if empty
|
|
240
|
+
if (value.length === 0) {
|
|
241
|
+
return _jsxs(_Fragment, {
|
|
242
|
+
children: [
|
|
243
|
+
_jsx(Text, { inverse: true, children: " " }),
|
|
244
|
+
_jsx(Text, { dimColor: true, children: placeholder }),
|
|
245
|
+
],
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
// Show value with cursor
|
|
249
|
+
const before = value.slice(0, cursorPos);
|
|
250
|
+
const cursor = value[cursorPos] || " ";
|
|
251
|
+
const after = value.slice(cursorPos + 1);
|
|
252
|
+
return _jsxs(Text, {
|
|
253
|
+
children: [before, _jsx(Text, { inverse: true, children: cursor }), after],
|
|
254
|
+
});
|
|
240
255
|
}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
export interface SingleSelectOption {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
label: string;
|
|
3
|
+
value: string;
|
|
4
|
+
description?: string;
|
|
5
5
|
}
|
|
6
6
|
export interface SingleSelectProps {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
options: SingleSelectOption[];
|
|
8
|
+
selected: string | null;
|
|
9
|
+
onChange: (selected: string) => void;
|
|
10
|
+
onSubmit: (selected: string) => void;
|
|
11
|
+
onCancel?: () => void;
|
|
12
12
|
}
|
|
13
|
-
export declare function SingleSelect({
|
|
13
|
+
export declare function SingleSelect({
|
|
14
|
+
options,
|
|
15
|
+
selected: _selected,
|
|
16
|
+
onChange,
|
|
17
|
+
onSubmit,
|
|
18
|
+
onCancel,
|
|
19
|
+
}: SingleSelectProps): import("react/jsx-runtime").JSX.Element;
|