Show tooltips for sidebar footer actions (#2025)

* fix(app): label sidebar footer actions

* fix(app): translate hosts tooltip
This commit is contained in:
Mohamed Boudra
2026-07-12 20:36:01 +02:00
committed by GitHub
parent a9ba0392b7
commit 18de06c2a4
10 changed files with 60 additions and 58 deletions

View File

@@ -101,9 +101,9 @@ interface SidebarSharedProps {
interface SidebarLabels {
addProject: string;
newWorkspace: string;
hosts: string;
home: string;
settings: string;
switchHost: string;
searchHosts: string;
sessions: string;
schedules: string;
@@ -226,9 +226,9 @@ export const LeftSidebar = memo(function LeftSidebar() {
(): SidebarLabels => ({
addProject: t("sidebar.actions.addProject"),
newWorkspace: t("sidebar.actions.newWorkspace"),
hosts: t("sidebar.actions.hosts"),
home: t("sidebar.actions.home"),
settings: t("sidebar.actions.settings"),
switchHost: t("sidebar.host.switchTitle"),
searchHosts: t("sidebar.host.searchPlaceholder"),
sessions: t("sidebar.sections.sessions"),
schedules: t("sidebar.sections.schedules"),
@@ -301,47 +301,58 @@ function FooterIconButton({
buttonRef,
onPress,
testID,
accessibilityLabel,
label,
icon: Icon,
iconSize,
shortcutKeys,
theme,
}: {
onPress: () => void;
testID: string;
accessibilityLabel: string;
label: string;
icon: typeof FolderPlus;
iconSize?: number;
shortcutKeys?: ReturnType<typeof useShortcutKeys>;
theme: SidebarTheme;
buttonRef?: RefObject<View | null>;
}) {
return (
<Pressable
ref={buttonRef}
style={styles.footerIconButton}
testID={testID}
nativeID={testID}
collapsable={false}
accessible
accessibilityLabel={accessibilityLabel}
accessibilityRole="button"
onPress={onPress}
>
{({ hovered }) => (
<Icon
size={iconSize ?? theme.iconSize.md}
color={hovered ? theme.colors.foreground : theme.colors.foregroundMuted}
/>
)}
</Pressable>
<Tooltip delayDuration={300}>
<TooltipTrigger asChild>
<Pressable
ref={buttonRef}
style={styles.footerIconButton}
testID={testID}
nativeID={testID}
collapsable={false}
accessible
accessibilityLabel={label}
accessibilityRole="button"
onPress={onPress}
>
{({ hovered }) => (
<Icon
size={iconSize ?? theme.iconSize.md}
color={hovered ? theme.colors.foreground : theme.colors.foregroundMuted}
/>
)}
</Pressable>
</TooltipTrigger>
<TooltipContent side="top" align="center" offset={8}>
<IconTooltipContent label={label} shortcutKeys={shortcutKeys} />
</TooltipContent>
</Tooltip>
);
}
function SidebarHostPicker({
theme,
label,
onAddHost,
onOpenHostSettings,
}: {
theme: SidebarTheme;
label: string;
onAddHost: () => void;
onOpenHostSettings: (serverId: string) => void;
}) {
@@ -380,7 +391,7 @@ function SidebarHostPicker({
buttonRef={triggerRef}
onPress={handleOpen}
testID="sidebar-hosts-trigger"
accessibilityLabel="Hosts"
label={label}
icon={Server}
iconSize={theme.iconSize.sm}
theme={theme}
@@ -389,22 +400,7 @@ function SidebarHostPicker({
);
}
function AddProjectTooltipContent({
newAgentKeys,
label,
}: {
newAgentKeys: ReturnType<typeof useShortcutKeys>;
label: string;
}) {
return (
<View style={styles.tooltipRow}>
<Text style={styles.tooltipText}>{label}</Text>
{newAgentKeys ? <Shortcut chord={newAgentKeys} /> : null}
</View>
);
}
function HeaderIconTooltipContent({
function IconTooltipContent({
label,
shortcutKeys,
}: {
@@ -489,50 +485,47 @@ function SidebarFooter({
handleSettings: () => void;
labels: {
addProject: string;
hosts: string;
home: string;
settings: string;
switchHost: string;
searchHosts: string;
};
handleAddHost: () => void;
handleOpenHostSettings: (serverId: string) => void;
}) {
const newAgentKeys = useShortcutKeys("new-agent");
const settingsKeys = useShortcutKeys("toggle-settings");
return (
<View style={styles.sidebarFooter}>
<View style={styles.footerIconRow}>
<SidebarHostPicker
theme={theme}
label={labels.hosts}
onAddHost={handleAddHost}
onOpenHostSettings={handleOpenHostSettings}
/>
<Tooltip delayDuration={300}>
<TooltipTrigger asChild>
<FooterIconButton
onPress={handleOpenProject}
testID="sidebar-add-project"
accessibilityLabel={labels.addProject}
icon={FolderPlus}
theme={theme}
/>
</TooltipTrigger>
<TooltipContent side="top" align="center" offset={8}>
<AddProjectTooltipContent newAgentKeys={newAgentKeys} label={labels.addProject} />
</TooltipContent>
</Tooltip>
<FooterIconButton
onPress={handleOpenProject}
testID="sidebar-add-project"
label={labels.addProject}
icon={FolderPlus}
shortcutKeys={newAgentKeys}
theme={theme}
/>
<FooterIconButton
onPress={handleHome}
testID="sidebar-home"
accessibilityLabel={labels.home}
label={labels.home}
icon={Home}
theme={theme}
/>
<FooterIconButton
onPress={handleSettings}
testID="sidebar-settings"
accessibilityLabel={labels.settings}
label={labels.settings}
icon={Settings}
shortcutKeys={settingsKeys}
theme={theme}
/>
</View>
@@ -876,7 +869,7 @@ function WorkspacesSectionHeader() {
</Pressable>
</TooltipTrigger>
<TooltipContent side="bottom" align="center" offset={8}>
<HeaderIconTooltipContent label="Search" shortcutKeys={commandCenterKeys} />
<IconTooltipContent label="Search" shortcutKeys={commandCenterKeys} />
</TooltipContent>
</Tooltip>
<Tooltip delayDuration={300}>
@@ -886,7 +879,7 @@ function WorkspacesSectionHeader() {
</View>
</TooltipTrigger>
<TooltipContent side="bottom" align="center" offset={8}>
<HeaderIconTooltipContent label="Display preferences" />
<IconTooltipContent label="Display preferences" />
</TooltipContent>
</Tooltip>
</View>

View File

@@ -370,6 +370,7 @@ describe("translation resources", () => {
expect(en.sidebar.host.switchTitle).toBe("Switch host");
expect(en.sidebar.host.searchPlaceholder).toBe("Search hosts...");
expect(en.sidebar.actions.addProject).toBe("Add project");
expect(en.sidebar.actions.hosts).toBe("Hosts");
expect(en.sidebar.actions.home).toBe("Home");
expect(en.sidebar.actions.settings).toBe("Settings");
expect(en.sidebar.actions.closeSidebar).toBe("Close sidebar");

View File

@@ -782,6 +782,7 @@ export const ar: TranslationResources = {
actions: {
addProject: "إضافة مشروع",
newWorkspace: "مساحة عمل جديدة",
hosts: "المضيفون",
home: "بيت",
settings: "إعدادات",
closeSidebar: "إغلاق الشريط الجانبي",

View File

@@ -789,6 +789,7 @@ export const en = {
actions: {
addProject: "Add project",
newWorkspace: "New workspace",
hosts: "Hosts",
home: "Home",
settings: "Settings",
closeSidebar: "Close sidebar",

View File

@@ -809,6 +809,7 @@ export const es: TranslationResources = {
actions: {
addProject: "Agregar proyecto",
newWorkspace: "Nuevo espacio de trabajo",
hosts: "Hosts",
home: "Hogar",
settings: "Ajustes",
closeSidebar: "Cerrar barra lateral",

View File

@@ -808,6 +808,7 @@ export const fr: TranslationResources = {
actions: {
addProject: "Ajouter un projet",
newWorkspace: "Nouvel espace de travail",
hosts: "Hôtes",
home: "Maison",
settings: "Paramètres",
closeSidebar: "Fermer la barre latérale",

View File

@@ -794,6 +794,7 @@ export const ja: TranslationResources = {
actions: {
addProject: "プロジェクトを追加",
newWorkspace: "新しいワークスペース",
hosts: "ホスト",
home: "ホーム",
settings: "設定",
closeSidebar: "サイドバーを閉じる",

View File

@@ -800,6 +800,7 @@ export const ptBR: TranslationResources = {
actions: {
addProject: "Adicionar projeto",
newWorkspace: "Novo workspace",
hosts: "Hosts",
home: "Início",
settings: "Configurações",
closeSidebar: "Fechar barra lateral",

View File

@@ -801,6 +801,7 @@ export const ru: TranslationResources = {
actions: {
addProject: "Добавить проект",
newWorkspace: "Новое рабочее пространство",
hosts: "Хосты",
home: "Дом",
settings: "Настройки",
closeSidebar: "Закрыть боковую панель",

View File

@@ -777,6 +777,7 @@ export const zhCN: TranslationResources = {
actions: {
addProject: "添加 project",
newWorkspace: "新建工作区",
hosts: "Hosts",
home: "首页",
settings: "设置",
closeSidebar: "关闭侧边栏",