feat(mobile): chat input keybinds + safe-area + tap targets + overflow safety
- ChatInput: e.nativeEvent.isComposing early-return added (CJK IME safety — first Enter of a composition no longer submits). Bare-Enter send path gated by !isMobile so mobile inserts a newline; send is button-only. Cmd/Ctrl+Enter and Shift+Cmd/Ctrl+Enter retained as desktop secondary bindings. Placeholder is now viewport-aware. Outer wrapper gets paddingBottom: env(safe-area-inset-bottom) so iOS home indicator doesn't overlap. - MessageBubble: ActionRow buttons (Copy / Regenerate / Fork / Trash) bumped to max-md min-h/min-w 44px; opacity-100 on mobile so actions don't hide behind a hover-to-reveal pattern. User bubble and assistant content wrapper gain break-words + min-w-0 so long unbreakable strings (URLs / paths) wrap rather than blowing out the column on narrow viewports. - ChatPane: queued-message dropdown + close X + Stop-generating button hit max-md 44px sizing. - ChatTabBar: per-tab X, +/History/Close-pane action buttons hit max-md 44px. Tab close X is force-visible on mobile (no hover-to-reveal). - M8: CodeBlock / Markdown tables / ToolCallCard already wrap overflow-x-auto pre-existing — no source change needed there; the break-words + min-w-0 additions above are the new defensive layer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -115,7 +115,7 @@ export function ChatTabBar({
|
||||
e.stopPropagation();
|
||||
onRemoveTab(chat.id);
|
||||
}}
|
||||
className="p-0.5 hover:bg-muted rounded opacity-0 group-hover:opacity-60 hover:!opacity-100 shrink-0"
|
||||
className="inline-flex items-center justify-center p-0.5 hover:bg-muted rounded opacity-0 group-hover:opacity-60 hover:!opacity-100 shrink-0 max-md:min-h-[44px] max-md:min-w-[44px] max-md:opacity-100"
|
||||
aria-label="Close tab"
|
||||
>
|
||||
<X size={10} />
|
||||
@@ -161,7 +161,7 @@ export function ChatTabBar({
|
||||
<button
|
||||
type="button"
|
||||
onClick={onNewChat}
|
||||
className="p-1 rounded text-muted-foreground hover:bg-muted hover:text-foreground"
|
||||
className="inline-flex items-center justify-center p-1 rounded text-muted-foreground hover:bg-muted hover:text-foreground max-md:min-h-[44px] max-md:min-w-[44px]"
|
||||
aria-label="New chat"
|
||||
title="New chat"
|
||||
>
|
||||
@@ -171,7 +171,7 @@ export function ChatTabBar({
|
||||
type="button"
|
||||
onClick={onShowHistory}
|
||||
className={cn(
|
||||
'p-1 rounded text-muted-foreground hover:bg-muted hover:text-foreground',
|
||||
'inline-flex items-center justify-center p-1 rounded text-muted-foreground hover:bg-muted hover:text-foreground max-md:min-h-[44px] max-md:min-w-[44px]',
|
||||
pane.kind === 'empty' && 'text-foreground bg-muted/50'
|
||||
)}
|
||||
aria-label="Session history"
|
||||
@@ -183,7 +183,7 @@ export function ChatTabBar({
|
||||
<button
|
||||
type="button"
|
||||
onClick={onRemovePane}
|
||||
className="p-1 rounded text-muted-foreground hover:bg-muted hover:text-foreground"
|
||||
className="inline-flex items-center justify-center p-1 rounded text-muted-foreground hover:bg-muted hover:text-foreground max-md:min-h-[44px] max-md:min-w-[44px]"
|
||||
aria-label="Close pane"
|
||||
title="Close pane"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user