Skip to content

Commit 4d1a6be

Browse files
committed
🤖 feat: move Mux logo from TitleBar to Projects header
- Replace 'Projects' h2 text with theme-aware MuxLogo component - Align logo with project chevrons (pl-4) and increase size (h-5) - Remove logo and shimmer animation from TitleBar - Keep update indicator (spinner/badge) and version/build metadata tooltip - Reduce desktop titlebar height from 40px to 36px (h-9) - Add DESKTOP_TITLEBAR_HEIGHT_CLASS constants to avoid duplication
1 parent 1fb196c commit 4d1a6be

File tree

5 files changed

+49
-60
lines changed

5 files changed

+49
-60
lines changed

src/browser/components/ProjectSidebar.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import React, { useState, useEffect, useCallback } from "react";
22
import { cn } from "@/common/lib/utils";
33
import { isDesktopMode } from "@/browser/hooks/useDesktopTitlebar";
4+
import MuxLogoDark from "@/browser/assets/logos/mux-logo-dark.svg?react";
5+
import MuxLogoLight from "@/browser/assets/logos/mux-logo-light.svg?react";
6+
import { useTheme } from "@/browser/contexts/ThemeContext";
47
import type { FrontendWorkspaceMetadata } from "@/common/types/workspace";
58
import { usePersistedState } from "@/browser/hooks/usePersistedState";
69
import { EXPANDED_PROJECTS_KEY } from "@/common/constants/storage";
@@ -241,6 +244,10 @@ const ProjectSidebarInner: React.FC<ProjectSidebarProps> = ({
241244
assignWorkspaceToSection,
242245
} = useProjectContext();
243246

247+
// Theme for logo variant
248+
const { theme } = useTheme();
249+
const MuxLogo = theme === "dark" || theme === "solarized-dark" ? MuxLogoDark : MuxLogoLight;
250+
244251
// Mobile breakpoint for auto-closing sidebar
245252
const MOBILE_BREAKPOINT = 768;
246253

@@ -483,8 +490,8 @@ const ProjectSidebarInner: React.FC<ProjectSidebarProps> = ({
483490
>
484491
{!collapsed && (
485492
<>
486-
<div className="border-dark flex items-center justify-between border-b p-4">
487-
<h2 className="text-foreground m-0 text-lg font-medium">Projects</h2>
493+
<div className="border-dark flex items-center justify-between border-b py-3 pr-3 pl-4">
494+
<MuxLogo className="h-5 w-[44px]" aria-label="Projects" />
488495
<button
489496
onClick={onAddProject}
490497
aria-label="Add project"

src/browser/components/RightSidebar/RightSidebarTabStrip.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import { CSS } from "@dnd-kit/utilities";
66
import { useDroppable, useDndContext } from "@dnd-kit/core";
77
import { Plus } from "lucide-react";
88
import type { TabType } from "@/browser/types/rightSidebar";
9-
import { isDesktopMode, getTitlebarRightInset } from "@/browser/hooks/useDesktopTitlebar";
9+
import {
10+
isDesktopMode,
11+
getTitlebarRightInset,
12+
DESKTOP_TITLEBAR_MIN_HEIGHT_CLASS,
13+
} from "@/browser/hooks/useDesktopTitlebar";
1014

1115
// Re-export for consumers that import from this file
1216
export { getTabName } from "./tabs";
@@ -141,7 +145,7 @@ export const RightSidebarTabStrip: React.FC<RightSidebarTabStripProps> = ({
141145
ref={setNodeRef}
142146
className={cn(
143147
"border-border-light flex min-w-0 items-center border-b px-2 transition-colors",
144-
isDesktop ? "min-h-10" : "py-1.5",
148+
isDesktop ? DESKTOP_TITLEBAR_MIN_HEIGHT_CLASS : "py-1.5",
145149
showDropHighlight && "bg-accent/30",
146150
isDraggingFromHere && "bg-accent/10",
147151
// In desktop mode, make header draggable for window movement

src/browser/components/TitleBar.tsx

Lines changed: 21 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import type { UpdateStatus } from "@/common/orpc/types";
77
import { Download, Loader2, RefreshCw } from "lucide-react";
88

99
import { useTutorial } from "@/browser/contexts/TutorialContext";
10-
import MuxLogoDark from "@/browser/assets/logos/mux-logo-dark.svg?react";
11-
import MuxLogoLight from "@/browser/assets/logos/mux-logo-light.svg?react";
12-
import { useTheme } from "@/browser/contexts/ThemeContext";
13-
1410
import { useAPI } from "@/browser/contexts/API";
15-
import { isDesktopMode, getTitlebarLeftInset } from "@/browser/hooks/useDesktopTitlebar";
11+
import {
12+
isDesktopMode,
13+
getTitlebarLeftInset,
14+
DESKTOP_TITLEBAR_HEIGHT_CLASS,
15+
} from "@/browser/hooks/useDesktopTitlebar";
1616

1717
// Update check intervals
1818
const UPDATE_CHECK_INTERVAL_MS = 4 * 60 * 60 * 1000; // 4 hours
@@ -75,11 +75,8 @@ function parseBuildInfo(version: unknown) {
7575

7676
export function TitleBar() {
7777
const { api } = useAPI();
78-
const { extendedTimestamp, gitDescribe } = parseBuildInfo(VERSION satisfies unknown);
78+
const { buildDate, extendedTimestamp, gitDescribe } = parseBuildInfo(VERSION satisfies unknown);
7979
const [updateStatus, setUpdateStatus] = useState<UpdateStatus>({ type: "idle" });
80-
81-
const { theme } = useTheme();
82-
const MuxLogo = theme === "dark" || theme === "solarized-dark" ? MuxLogoDark : MuxLogoLight;
8380
const [isCheckingOnHover, setIsCheckingOnHover] = useState(false);
8481
const lastHoverCheckTime = useRef<number>(0);
8582

@@ -175,7 +172,11 @@ export function TitleBar() {
175172

176173
const getUpdateTooltip = () => {
177174
const currentVersion = gitDescribe ?? "dev";
178-
const lines: React.ReactNode[] = [`Current: ${currentVersion}`];
175+
const lines: React.ReactNode[] = [
176+
`Current: ${currentVersion}`,
177+
`Built: ${buildDate}`,
178+
`Built at: ${extendedTimestamp}`,
179+
];
179180

180181
if (!window.api) {
181182
lines.push("Desktop updates are available in the Electron app only.");
@@ -223,8 +224,6 @@ export function TitleBar() {
223224
);
224225
};
225226

226-
const showUpdateShimmer = updateStatus.type === "available";
227-
228227
const updateBadgeIcon = (() => {
229228
if (updateStatus.type === "available") {
230229
return <Download className="size-3.5" />;
@@ -256,7 +255,7 @@ export function TitleBar() {
256255
<div
257256
className={cn(
258257
"bg-sidebar border-border-light font-primary text-muted flex shrink-0 items-center justify-between border-b px-4 text-[11px] select-none",
259-
isDesktop ? "h-10" : "h-8",
258+
isDesktop ? DESKTOP_TITLEBAR_HEIGHT_CLASS : "h-8",
260259
// In desktop mode, make header draggable for window movement
261260
isDesktop && "titlebar-drag"
262261
)}
@@ -273,63 +272,31 @@ export function TitleBar() {
273272
<TooltipTrigger asChild>
274273
<div
275274
className={cn(
276-
"flex items-center gap-1",
275+
"flex items-center gap-1.5",
277276
isUpdateActionable ? "cursor-pointer hover:opacity-70" : "cursor-default"
278277
)}
279278
onClick={handleUpdateClick}
280279
onMouseEnter={handleIndicatorHover}
281280
>
282281
<div
283282
className={cn(
284-
"relative overflow-hidden",
285-
leftInset > 0 ? "h-3 w-[26px]" : "h-4 w-[35px]"
286-
)}
287-
>
288-
<MuxLogo
289-
className={cn("block h-full w-full", leftInset > 0 || "-translate-y-px")}
290-
/>
291-
{showUpdateShimmer && (
292-
<div
293-
className="pointer-events-none absolute inset-0 animate-[shimmer-slide_2.5s_infinite_linear]"
294-
data-chromatic="ignore"
295-
style={{
296-
background:
297-
"linear-gradient(90deg, transparent 0%, transparent 40%, color-mix(in srgb, var(--color-accent) 35%, transparent) 50%, transparent 60%, transparent 100%)",
298-
width: "300%",
299-
marginLeft: "-180%",
300-
}}
301-
/>
302-
)}
303-
</div>
304-
<div
305-
className={cn(
306-
"text-accent flex items-center justify-center",
307-
leftInset > 0 ? "h-3 w-3" : "h-3.5 w-3.5"
283+
"min-w-0 cursor-text truncate font-normal tracking-wider select-text",
284+
leftInset > 0 ? "text-[10px]" : "text-xs"
308285
)}
309286
>
310-
{updateBadgeIcon}
287+
{gitDescribe ?? "(dev)"}
311288
</div>
289+
{updateBadgeIcon && (
290+
<div className="text-accent flex h-3.5 w-3.5 items-center justify-center">
291+
{updateBadgeIcon}
292+
</div>
293+
)}
312294
</div>
313295
</TooltipTrigger>
314296
<TooltipContent align="start" className="pointer-events-auto">
315297
{getUpdateTooltip()}
316298
</TooltipContent>
317299
</Tooltip>
318-
<Tooltip>
319-
<TooltipTrigger asChild>
320-
<div
321-
className={cn(
322-
"min-w-0 cursor-text truncate font-normal tracking-wider select-text",
323-
leftInset > 0 ? "text-[10px]" : "text-xs"
324-
)}
325-
>
326-
{gitDescribe ?? "(dev)"}
327-
</div>
328-
</TooltipTrigger>
329-
<TooltipContent side="bottom" align="start">
330-
Built at {extendedTimestamp}
331-
</TooltipContent>
332-
</Tooltip>
333300
</div>
334301
{isDesktop ? (
335302
<div className="titlebar-no-drag">

src/browser/components/WorkspaceHeader.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ import { useTutorial } from "@/browser/contexts/TutorialContext";
1616
import { useOpenTerminal } from "@/browser/hooks/useOpenTerminal";
1717
import { useOpenInEditor } from "@/browser/hooks/useOpenInEditor";
1818
import { usePersistedState } from "@/browser/hooks/usePersistedState";
19-
import { getTitlebarRightInset, isDesktopMode } from "@/browser/hooks/useDesktopTitlebar";
19+
import {
20+
getTitlebarRightInset,
21+
isDesktopMode,
22+
DESKTOP_TITLEBAR_HEIGHT_CLASS,
23+
} from "@/browser/hooks/useDesktopTitlebar";
2024
import { WorkspaceLinks } from "./WorkspaceLinks";
2125

2226
interface WorkspaceHeaderProps {
@@ -99,7 +103,7 @@ export const WorkspaceHeader: React.FC<WorkspaceHeaderProps> = ({
99103
data-testid="workspace-header"
100104
className={cn(
101105
"bg-sidebar border-border-light flex items-center justify-between border-b px-[15px] [@media(max-width:768px)]:h-auto [@media(max-width:768px)]:flex-wrap [@media(max-width:768px)]:gap-2 [@media(max-width:768px)]:py-2 [@media(max-width:768px)]:pl-[60px]",
102-
isDesktop ? "h-10" : "h-8",
106+
isDesktop ? DESKTOP_TITLEBAR_HEIGHT_CLASS : "h-8",
103107
// In desktop mode, make header draggable for window movement
104108
isDesktop && "titlebar-drag"
105109
)}

src/browser/hooks/useDesktopTitlebar.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ export const MAC_TRAFFIC_LIGHTS_INSET = 80;
5050
*/
5151
export const WIN_LINUX_OVERLAY_INSET = 138;
5252

53+
/**
54+
* Tailwind height classes for the desktop titlebar.
55+
* Use these in components that need to align with the titlebar height.
56+
*/
57+
export const DESKTOP_TITLEBAR_HEIGHT_CLASS = "h-9"; // 36px
58+
export const DESKTOP_TITLEBAR_MIN_HEIGHT_CLASS = "min-h-9"; // 36px
59+
5360
/**
5461
* Returns the left inset needed for macOS traffic lights.
5562
* Returns 0 if not in desktop mode or not on macOS.

0 commit comments

Comments
 (0)