Date: Fri, 15 May 2026 00:54:52 +0800
Subject: [PATCH 09/11] fix(i18n): remove unused resize handle aria labels
---
packages/ui/src/lib/i18n/messages/en/messaging.ts | 1 -
packages/ui/src/lib/i18n/messages/es/messaging.ts | 1 -
packages/ui/src/lib/i18n/messages/fr/messaging.ts | 1 -
packages/ui/src/lib/i18n/messages/he/messaging.ts | 1 -
packages/ui/src/lib/i18n/messages/ja/messaging.ts | 1 -
packages/ui/src/lib/i18n/messages/ru/messaging.ts | 1 -
packages/ui/src/lib/i18n/messages/zh-Hans/messaging.ts | 1 -
7 files changed, 7 deletions(-)
diff --git a/packages/ui/src/lib/i18n/messages/en/messaging.ts b/packages/ui/src/lib/i18n/messages/en/messaging.ts
index bf7e6301b..31700b64d 100644
--- a/packages/ui/src/lib/i18n/messages/en/messaging.ts
+++ b/packages/ui/src/lib/i18n/messages/en/messaging.ts
@@ -182,6 +182,5 @@ export const messagingMessages = {
"promptInput.voiceInput.error.permissionDenied": "Microphone access was denied by macOS.",
"promptInput.voiceInput.error.unsupported": "Voice input is not supported in this browser.",
"promptInput.voiceInput.error.transcribe": "Unable to transcribe the recorded audio.",
- "promptInput.resizeHandle.ariaLabel": "Resize input height",
"promptInput.resizeHandle.title": "Drag to resize input height",
} as const
diff --git a/packages/ui/src/lib/i18n/messages/es/messaging.ts b/packages/ui/src/lib/i18n/messages/es/messaging.ts
index 422f85017..a2e88568d 100644
--- a/packages/ui/src/lib/i18n/messages/es/messaging.ts
+++ b/packages/ui/src/lib/i18n/messages/es/messaging.ts
@@ -185,5 +185,4 @@ export const messagingMessages = {
"promptInput.voiceInput.error.permissionDenied": "macOS denegó el acceso al micrófono.",
"promptInput.voiceInput.error.unsupported": "La entrada de voz no es compatible con este navegador.",
"promptInput.voiceInput.error.transcribe": "No se pudo transcribir el audio grabado.",
- "promptInput.resizeHandle.ariaLabel": "Redimensionar altura de entrada",
} as const
diff --git a/packages/ui/src/lib/i18n/messages/fr/messaging.ts b/packages/ui/src/lib/i18n/messages/fr/messaging.ts
index 233404708..c15477e24 100644
--- a/packages/ui/src/lib/i18n/messages/fr/messaging.ts
+++ b/packages/ui/src/lib/i18n/messages/fr/messaging.ts
@@ -185,5 +185,4 @@ export const messagingMessages = {
"promptInput.voiceInput.error.permissionDenied": "macOS a refusé l'accès au microphone.",
"promptInput.voiceInput.error.unsupported": "La saisie vocale n'est pas prise en charge dans ce navigateur.",
"promptInput.voiceInput.error.transcribe": "Impossible de transcrire l'audio enregistré.",
- "promptInput.resizeHandle.ariaLabel": "Redimensionner la hauteur",
} as const
diff --git a/packages/ui/src/lib/i18n/messages/he/messaging.ts b/packages/ui/src/lib/i18n/messages/he/messaging.ts
index e297bf9d1..537db2db2 100644
--- a/packages/ui/src/lib/i18n/messages/he/messaging.ts
+++ b/packages/ui/src/lib/i18n/messages/he/messaging.ts
@@ -183,5 +183,4 @@ export const messagingMessages = {
"promptInput.voiceInput.error.permissionDenied": "הגישה למיקרופון נדחתה על ידי macOS.",
"promptInput.voiceInput.error.unsupported": "קלט קולי אינו נתמך בדפדפן זה.",
"promptInput.voiceInput.error.transcribe": "לא ניתן היה לתמלל את האודיו שהוקלט.",
- "promptInput.resizeHandle.ariaLabel": "שנה גובה",
} as const
diff --git a/packages/ui/src/lib/i18n/messages/ja/messaging.ts b/packages/ui/src/lib/i18n/messages/ja/messaging.ts
index 2b15e6959..013d9b60b 100644
--- a/packages/ui/src/lib/i18n/messages/ja/messaging.ts
+++ b/packages/ui/src/lib/i18n/messages/ja/messaging.ts
@@ -185,5 +185,4 @@ export const messagingMessages = {
"promptInput.voiceInput.error.permissionDenied": "macOS によりマイクへのアクセスが拒否されました。",
"promptInput.voiceInput.error.unsupported": "このブラウザーでは音声入力はサポートされていません。",
"promptInput.voiceInput.error.transcribe": "録音した音声を文字起こしできませんでした。",
- "promptInput.resizeHandle.ariaLabel": "入力の高さを変更",
} as const
diff --git a/packages/ui/src/lib/i18n/messages/ru/messaging.ts b/packages/ui/src/lib/i18n/messages/ru/messaging.ts
index 628ea4c68..a4ce41f2b 100644
--- a/packages/ui/src/lib/i18n/messages/ru/messaging.ts
+++ b/packages/ui/src/lib/i18n/messages/ru/messaging.ts
@@ -185,5 +185,4 @@ export const messagingMessages = {
"promptInput.voiceInput.error.permissionDenied": "macOS запретила доступ к микрофону.",
"promptInput.voiceInput.error.unsupported": "Голосовой ввод не поддерживается в этом браузере.",
"promptInput.voiceInput.error.transcribe": "Не удалось расшифровать записанное аудио.",
- "promptInput.resizeHandle.ariaLabel": "Изменить высоту",
} as const
diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/messaging.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/messaging.ts
index d1ef36781..b00f7e676 100644
--- a/packages/ui/src/lib/i18n/messages/zh-Hans/messaging.ts
+++ b/packages/ui/src/lib/i18n/messages/zh-Hans/messaging.ts
@@ -184,6 +184,5 @@ export const messagingMessages = {
"promptInput.voiceInput.error.permissionDenied": "macOS 已拒绝麦克风访问。",
"promptInput.voiceInput.error.unsupported": "此浏览器不支持语音输入。",
"promptInput.voiceInput.error.transcribe": "无法转写录制的音频。",
- "promptInput.resizeHandle.ariaLabel": "调整输入框高度",
"promptInput.resizeHandle.title": "拖动以调整输入框高度",
} as const
From 62ddb371a4d510875ddbe2477105ac35ca960587 Mon Sep 17 00:00:00 2001
From: Shantur Rathore
Date: Fri, 15 May 2026 14:23:04 +0100
Subject: [PATCH 10/11] fix(ui): cap prompt resize height
Limit manual prompt resizing to sixty percent of the local session center so the composer cannot consume the full message area.
The resize handle now lives inside the prompt field container, keeping the affordance visually centered over the text editor instead of spanning the full composer chrome. Removing the toolbar lookup also drops the temporary data attribute from the session toolbar and avoids cross-pane DOM coupling.
Validation: npm run typecheck --workspace @codenomad/ui; npm run build --workspace @codenomad/ui.
---
.../components/instance/instance-shell2.tsx | 2 +-
packages/ui/src/components/prompt-input.tsx | 69 +++++++------------
.../ui/src/styles/messaging/prompt-input.css | 8 +--
3 files changed, 30 insertions(+), 49 deletions(-)
diff --git a/packages/ui/src/components/instance/instance-shell2.tsx b/packages/ui/src/components/instance/instance-shell2.tsx
index ba91fb387..f23ec071b 100644
--- a/packages/ui/src/components/instance/instance-shell2.tsx
+++ b/packages/ui/src/components/instance/instance-shell2.tsx
@@ -837,7 +837,7 @@ const InstanceShell2: Component = (props) => {
>
-
+
import("./unified-picker"))
+const DEFAULT_PROMPT_FIELD_HEIGHT = 104
+const MAX_PROMPT_FIELD_HEIGHT_RATIO = 0.6
function getConsumedPastedTextAttachmentIds(text: string, attachments: Attachment[]): string[] {
if (!text || attachments.length === 0) return []
@@ -304,44 +306,23 @@ export default function PromptInput(props: PromptInputProps) {
})
function computeMaxFieldHeight(): number {
- if (typeof window === "undefined") return 280
+ if (typeof window === "undefined") return DEFAULT_PROMPT_FIELD_HEIGHT
- const currentFieldHeight = fieldContainerRef?.getBoundingClientRect().height ?? 104
- const wrapperHeight = wrapperRef?.getBoundingClientRect().height ?? currentFieldHeight
- const nonFieldHeight = Math.max(0, wrapperHeight - currentFieldHeight)
- const padding = 16
-
- if (!wrapperRef) {
- return Math.max(104, window.innerHeight - 100 - nonFieldHeight)
- }
-
- const wrapperRect = wrapperRef.getBoundingClientRect()
- const localToolbar =
- wrapperRef.closest('.session-view')?.querySelector('.session-toolbar') ||
- wrapperRef.closest('[data-session-center-width]')?.querySelector('.session-toolbar')
- const toolbar =
- localToolbar ||
- document.querySelector('[data-session-toolbar="true"]') ||
- document.querySelector('.session-toolbar')
-
- if (toolbar) {
- const toolbarRect = toolbar.getBoundingClientRect()
- const availableTotalHeight = wrapperRect.bottom - toolbarRect.bottom - padding
- return Math.max(104, availableTotalHeight - nonFieldHeight)
- }
-
- return Math.max(104, window.innerHeight - 100 - nonFieldHeight)
+ const sessionCenter = wrapperRef?.closest("[data-session-center-width]")
+ const availableHeight = sessionCenter?.getBoundingClientRect().height ?? window.innerHeight
+ const maxHeight = Math.floor(availableHeight * MAX_PROMPT_FIELD_HEIGHT_RATIO)
+ return Math.max(DEFAULT_PROMPT_FIELD_HEIGHT, maxHeight)
}
function cleanupResizeTracking(): void {
if (activePointerMoveHandler) {
- document.removeEventListener('pointermove', activePointerMoveHandler)
+ document.removeEventListener("pointermove", activePointerMoveHandler)
activePointerMoveHandler = undefined
}
if (activePointerUpHandler) {
- document.removeEventListener('pointerup', activePointerUpHandler)
- document.removeEventListener('pointercancel', activePointerUpHandler)
+ document.removeEventListener("pointerup", activePointerUpHandler)
+ document.removeEventListener("pointercancel", activePointerUpHandler)
activePointerUpHandler = undefined
}
@@ -374,13 +355,13 @@ export default function PromptInput(props: PromptInputProps) {
}
const startY = event.clientY
- const startHeight = fieldContainerRef?.getBoundingClientRect().height ?? 104
+ const startHeight = fieldContainerRef?.getBoundingClientRect().height ?? DEFAULT_PROMPT_FIELD_HEIGHT
const computedMax = computeMaxFieldHeight()
function handlePointerMove(moveEvent: PointerEvent) {
moveEvent.preventDefault()
const deltaY = startY - moveEvent.clientY
- const nextHeight = Math.max(104, Math.min(computedMax, startHeight + deltaY))
+ const nextHeight = Math.max(DEFAULT_PROMPT_FIELD_HEIGHT, Math.min(computedMax, startHeight + deltaY))
setInputHeight(nextHeight)
}
@@ -392,9 +373,9 @@ export default function PromptInput(props: PromptInputProps) {
activePointerMoveHandler = handlePointerMove
activePointerUpHandler = handlePointerUp
- document.addEventListener('pointermove', handlePointerMove)
- document.addEventListener('pointerup', handlePointerUp)
- document.addEventListener('pointercancel', handlePointerUp)
+ document.addEventListener("pointermove", handlePointerMove)
+ document.addEventListener("pointerup", handlePointerUp)
+ document.addEventListener("pointercancel", handlePointerUp)
}
onCleanup(() => {
@@ -707,13 +688,6 @@ export default function PromptInput(props: PromptInputProps) {
return (