Improve mobile terminal keyboard layout

This commit is contained in:
Mohamed Boudra
2026-05-25 19:26:38 +07:00
parent 5dd2afaac9
commit 9806a893ed
+56 -24
View File
@@ -2,7 +2,6 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { import {
ActivityIndicator, ActivityIndicator,
Pressable, Pressable,
ScrollView,
Text, Text,
View, View,
type PressableStateCallbackType, type PressableStateCallbackType,
@@ -67,17 +66,17 @@ const MODIFIER_LABELS = {
alt: "Alt", alt: "Alt",
} as const; } as const;
const KEY_BUTTONS: Array<{ id: string; label: string; key: string }> = [ const KEY_BUTTONS = {
{ id: "esc", label: "Esc", key: "Escape" }, esc: { id: "esc", label: "Esc", key: "Escape" },
{ id: "tab", label: "Tab", key: "Tab" }, tab: { id: "tab", label: "Tab", key: "Tab" },
{ id: "up", label: "↑", key: "ArrowUp" }, up: { id: "up", label: "↑", key: "ArrowUp" },
{ id: "down", label: "↓", key: "ArrowDown" }, down: { id: "down", label: "↓", key: "ArrowDown" },
{ id: "left", label: "←", key: "ArrowLeft" }, left: { id: "left", label: "←", key: "ArrowLeft" },
{ id: "right", label: "→", key: "ArrowRight" }, right: { id: "right", label: "→", key: "ArrowRight" },
{ id: "enter", label: "Enter", key: "Enter" }, enter: { id: "enter", label: "Enter", key: "Enter" },
{ id: "backspace", label: "⌫", key: "Backspace" }, backspace: { id: "backspace", label: "⌫", key: "Backspace" },
{ id: "c", label: "C", key: "c" }, space: { id: "space", label: "Space", key: " " },
]; } as const;
interface ModifierState { interface ModifierState {
ctrl: boolean; ctrl: boolean;
@@ -797,18 +796,47 @@ export function TerminalPane({
{isMobile ? ( {isMobile ? (
<View style={styles.keyboardContainer} testID="terminal-virtual-keyboard"> <View style={styles.keyboardContainer} testID="terminal-virtual-keyboard">
<ScrollView horizontal showsHorizontalScrollIndicator={false}> <View style={styles.keyboardRows}>
<View style={styles.keyboardRow}> <View style={styles.keyboardRow}>
{(Object.keys(MODIFIER_LABELS) as Array<keyof ModifierState>).map((modifier) => ( {[KEY_BUTTONS.esc, KEY_BUTTONS.tab].map((button) => (
<ModifierButton <VirtualKeyButton
key={modifier} key={button.id}
modifier={modifier} id={button.id}
active={modifiers[modifier]} label={button.label}
onToggle={toggleModifier} keyValue={button.key}
onSend={sendVirtualKey}
/> />
))} ))}
{KEY_BUTTONS.map((button) => ( <ModifierButton modifier="ctrl" active={modifiers.ctrl} onToggle={toggleModifier} />
<VirtualKeyButton
id={KEY_BUTTONS.up.id}
label={KEY_BUTTONS.up.label}
keyValue={KEY_BUTTONS.up.key}
onSend={sendVirtualKey}
/>
<ModifierButton modifier="shift" active={modifiers.shift} onToggle={toggleModifier} />
<VirtualKeyButton
id={KEY_BUTTONS.backspace.id}
label={KEY_BUTTONS.backspace.label}
keyValue={KEY_BUTTONS.backspace.key}
onSend={sendVirtualKey}
/>
</View>
<View style={styles.keyboardRow}>
<ModifierButton modifier="alt" active={modifiers.alt} onToggle={toggleModifier} />
{[
KEY_BUTTONS.space,
KEY_BUTTONS.left,
KEY_BUTTONS.down,
KEY_BUTTONS.right,
KEY_BUTTONS.enter,
].map((button) => (
<VirtualKeyButton <VirtualKeyButton
key={button.id} key={button.id}
id={button.id} id={button.id}
@@ -818,7 +846,7 @@ export function TerminalPane({
/> />
))} ))}
</View> </View>
</ScrollView> </View>
</View> </View>
) : null} ) : null}
</Animated.View> </Animated.View>
@@ -865,21 +893,24 @@ const styles = StyleSheet.create((theme) => ({
paddingHorizontal: theme.spacing[2], paddingHorizontal: theme.spacing[2],
paddingVertical: theme.spacing[2], paddingVertical: theme.spacing[2],
}, },
keyboardRows: {
gap: theme.spacing[1],
},
keyboardRow: { keyboardRow: {
flexDirection: "row", flexDirection: "row",
alignItems: "center", alignItems: "center",
gap: theme.spacing[1], gap: theme.spacing[1],
paddingRight: theme.spacing[3],
}, },
keyButton: { keyButton: {
minWidth: 44, flex: 1,
minWidth: 0,
height: 34, height: 34,
borderRadius: theme.borderRadius.md, borderRadius: theme.borderRadius.md,
borderWidth: 1, borderWidth: 1,
borderColor: theme.colors.border, borderColor: theme.colors.border,
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "center",
paddingHorizontal: theme.spacing[2], paddingHorizontal: theme.spacing[1],
backgroundColor: theme.colors.surface1, backgroundColor: theme.colors.surface1,
}, },
keyButtonHovered: { keyButtonHovered: {
@@ -893,6 +924,7 @@ const styles = StyleSheet.create((theme) => ({
color: theme.colors.foregroundMuted, color: theme.colors.foregroundMuted,
fontSize: theme.fontSize.sm, fontSize: theme.fontSize.sm,
fontWeight: theme.fontWeight.medium, fontWeight: theme.fontWeight.medium,
textAlign: "center",
}, },
keyButtonTextActive: { keyButtonTextActive: {
color: theme.colors.foreground, color: theme.colors.foreground,