mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
feat: add stacked layout for chat input when content wraps
Add dynamic layout switching that moves input buttons below the text area when content height exceeds initial height. Includes height tracking, state management via checkStacked(), and CSS grid updates for stacked mode on desktop only.
This commit is contained in:
parent
e0a5dc6582
commit
5f63f7c744
1 changed files with 44 additions and 1 deletions
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
let userInstructionAreaActive: boolean = false;
|
||||
let userInstructionActive: boolean = true;
|
||||
let stacked: boolean = false;
|
||||
|
||||
let userRequest: string = "";
|
||||
|
||||
|
|
@ -57,6 +58,7 @@
|
|||
|
||||
let countdownIntervalId: ReturnType<typeof setInterval> | null = null;
|
||||
let countdownSecondsRemaining: number = 0;
|
||||
let inputInitialHeight: number = 0;
|
||||
|
||||
const diffOpenedRef: EventRef = eventService.on(Event.DiffOpened, () => { inputMode = InputMode.Diff; focusInput(); });
|
||||
const diffClosedRef: EventRef = eventService.on(Event.DiffClosed, () => { inputMode = InputMode.Normal; focusInput(); });
|
||||
|
|
@ -64,6 +66,7 @@
|
|||
|
||||
onMount(async () => {
|
||||
userInstructionActive = (await aiPrompt.userInstruction()).trim() !== "";
|
||||
inputInitialHeight = textareaElement.innerHeight;
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
|
|
@ -73,6 +76,18 @@
|
|||
stopCountdown();
|
||||
});
|
||||
|
||||
function checkStacked() {
|
||||
if (textareaElement.textContent.trim() === "") {
|
||||
stacked = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (textareaElement.innerHeight > inputInitialHeight) {
|
||||
stacked = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
export function focusInput(onMobile: boolean = false) {
|
||||
// don't focus on mobile, it's annoying
|
||||
if (onMobile || !Platform.isMobile) {
|
||||
|
|
@ -247,6 +262,7 @@
|
|||
|
||||
textareaElement.textContent = "";
|
||||
userRequest = "";
|
||||
checkStacked();
|
||||
|
||||
if (Platform.isMobile) {
|
||||
textareaElement.blur();
|
||||
|
|
@ -399,6 +415,8 @@
|
|||
if (userRequest.trim() === "") {
|
||||
textareaElement.textContent = "";
|
||||
}
|
||||
|
||||
checkStacked();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -471,7 +489,7 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<div id="input-container" class:edit-mode={editModeActive}>
|
||||
<div id="input-container" class:edit-mode={editModeActive} class:stacked>
|
||||
<div id="input-display-container" style:padding-top={attachments.length > 0 ? "var(--size-4-2)" : 0}>
|
||||
<InputDisplay bind:this={inputDisplay} {editModeActive}/>
|
||||
</div>
|
||||
|
|
@ -739,6 +757,31 @@
|
|||
background-color: var(--alt-interactive-accent-hover);
|
||||
}
|
||||
|
||||
/* Stacked layout: input above, buttons below (desktop only, when content wraps) */
|
||||
#input-container.stacked {
|
||||
grid-template-rows: auto auto auto auto var(--size-4-3) 1fr var(--size-4-2) auto var(--size-4-3);
|
||||
}
|
||||
|
||||
#input-container.stacked #input-field {
|
||||
grid-column: 2 / 11;
|
||||
}
|
||||
|
||||
#input-container.stacked #user-instruction-button {
|
||||
grid-row: 8;
|
||||
}
|
||||
|
||||
#input-container.stacked #edit-mode-button {
|
||||
grid-row: 8;
|
||||
}
|
||||
|
||||
#input-container.stacked #planning-mode-button {
|
||||
grid-row: 8;
|
||||
}
|
||||
|
||||
#input-container.stacked #submit-button {
|
||||
grid-row: 8;
|
||||
}
|
||||
|
||||
/* Narrow/mobile layout: input above, buttons below */
|
||||
:global(.is-mobile) #input-container {
|
||||
grid-template-rows: auto auto auto auto var(--size-4-3) 1fr var(--size-4-2) auto var(--size-4-3);
|
||||
|
|
|
|||
Loading…
Reference in a new issue