feat(tui): add multiline chat input with dynamic height
- Support Shift+Enter to insert newlines in chat input - Chat input container expands dynamically up to 8 lines - Enter key sends message as before - Fix cursor line background to match unselected lines
This commit is contained in:
@@ -117,7 +117,7 @@ Screen {
|
||||
margin-right: 0;
|
||||
padding: 0;
|
||||
layout: horizontal;
|
||||
align-vertical: middle;
|
||||
align-vertical: top;
|
||||
}
|
||||
|
||||
#chat_input_container:focus-within {
|
||||
@@ -134,7 +134,7 @@ Screen {
|
||||
height: 100%;
|
||||
padding: 0 0 0 1;
|
||||
color: #737373;
|
||||
content-align-vertical: middle;
|
||||
content-align-vertical: top;
|
||||
}
|
||||
|
||||
#chat_history:focus {
|
||||
@@ -144,7 +144,7 @@ Screen {
|
||||
#chat_input {
|
||||
width: 1fr;
|
||||
height: 100%;
|
||||
background: #121212;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: #d4d4d4;
|
||||
padding: 0;
|
||||
@@ -155,6 +155,14 @@ Screen {
|
||||
border: none;
|
||||
}
|
||||
|
||||
#chat_input .text-area--cursor-line {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
#chat_input:focus .text-area--cursor-line {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
#chat_input > .text-area--placeholder {
|
||||
color: #525252;
|
||||
text-style: italic;
|
||||
|
||||
@@ -55,7 +55,15 @@ class ChatTextArea(TextArea): # type: ignore[misc]
|
||||
def set_app_reference(self, app: "StrixTUIApp") -> None:
|
||||
self._app_reference = app
|
||||
|
||||
def on_mount(self) -> None:
|
||||
self._update_height()
|
||||
|
||||
def _on_key(self, event: events.Key) -> None:
|
||||
if event.key == "shift+enter":
|
||||
self.insert("\n")
|
||||
event.prevent_default()
|
||||
return
|
||||
|
||||
if event.key == "enter" and self._app_reference:
|
||||
text_content = str(self.text) # type: ignore[has-type]
|
||||
message = text_content.strip()
|
||||
@@ -69,6 +77,20 @@ class ChatTextArea(TextArea): # type: ignore[misc]
|
||||
|
||||
super()._on_key(event)
|
||||
|
||||
@on(TextArea.Changed) # type: ignore[misc]
|
||||
def _update_height(self, _event: TextArea.Changed | None = None) -> None:
|
||||
if not self.parent:
|
||||
return
|
||||
|
||||
line_count = self.document.line_count
|
||||
target_lines = min(max(1, line_count), 8)
|
||||
|
||||
new_height = target_lines + 2
|
||||
|
||||
if self.parent.styles.height != new_height:
|
||||
self.parent.styles.height = new_height
|
||||
self.scroll_cursor_visible()
|
||||
|
||||
|
||||
class SplashScreen(Static): # type: ignore[misc]
|
||||
PRIMARY_GREEN = "#22c55e"
|
||||
|
||||
Reference in New Issue
Block a user