Skip to content

Commit d006371

Browse files
committed
update styling for some of the icons, fix gaps, simplify, more tailwind
1 parent e9fd7be commit d006371

3 files changed

Lines changed: 63 additions & 66 deletions

File tree

frontend/app/tab/tabbar.scss

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,6 @@
4040
border: 1px solid var(--border-color);
4141
}
4242

43-
.tab-bar-right {
44-
display: flex;
45-
flex-direction: row;
46-
gap: 6px;
47-
height: 100%;
48-
align-items: center;
49-
margin-left: auto;
50-
}
51-
5243
.add-tab {
5344
padding: 0 10px;
5445
height: 27px;

frontend/app/tab/tabbar.tsx

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright 2026, Command Line Inc.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
import { Button } from "@/app/element/button";
54
import { Tooltip } from "@/app/element/tooltip";
65
import { modalsModel } from "@/app/store/modalmodel";
76
import { TabRpcClient } from "@/app/store/wshrpcutil";
@@ -13,7 +12,6 @@ import { useAtomValue } from "jotai";
1312
import { OverlayScrollbars } from "overlayscrollbars";
1413
import { createRef, memo, useCallback, useEffect, useRef, useState } from "react";
1514
import { debounce } from "throttle-debounce";
16-
import { IconButton } from "../element/iconbutton";
1715
import { Tab } from "./tab";
1816
import "./tabbar.scss";
1917
import { TabBarEnv } from "./tabbarenv";
@@ -110,7 +108,7 @@ const ConfigErrorMessage = () => {
110108
);
111109
};
112110

113-
const ConfigErrorIcon = ({ buttonRef }: { buttonRef: React.RefObject<HTMLElement> }) => {
111+
const ConfigErrorIcon = () => {
114112
const env = useWaveEnv<TabBarEnv>();
115113
const fullConfig = useAtomValue(env.atoms.fullConfigAtom);
116114

@@ -122,14 +120,16 @@ const ConfigErrorIcon = ({ buttonRef }: { buttonRef: React.RefObject<HTMLElement
122120
return null;
123121
}
124122
return (
125-
<Button
126-
ref={buttonRef as React.RefObject<HTMLButtonElement>}
127-
className="text-black flex-[0_0_fit-content] !h-full !px-3 red"
128-
onClick={handleClick}
123+
<Tooltip
124+
content="Configuration Error"
125+
placement="bottom"
126+
hideOnClick
127+
divClassName="flex h-[22px] px-2 mb-1 items-center rounded-md box-border cursor-pointer hover:bg-hoverbg transition-colors text-[12px] text-error"
128+
divStyle={{ WebkitAppRegion: "no-drag" } as React.CSSProperties}
129+
divOnClick={handleClick}
129130
>
130-
<i className="fa fa-solid fa-exclamation-triangle" />
131-
Config Error
132-
</Button>
131+
<i className="fa fa-solid fa-triangle-exclamation" />
132+
</Tooltip>
133133
);
134134
};
135135

@@ -178,14 +178,12 @@ const TabBar = memo(({ workspace }: TabBarProps) => {
178178
});
179179
const osInstanceRef = useRef<OverlayScrollbars>(null);
180180
const draggerLeftRef = useRef<HTMLDivElement>(null);
181-
const draggerRightRef = useRef<HTMLDivElement>(null);
181+
const rightContainerRef = useRef<HTMLDivElement>(null);
182182
const workspaceSwitcherRef = useRef<HTMLDivElement>(null);
183183
const waveAIButtonRef = useRef<HTMLDivElement>(null);
184184
const appMenuButtonRef = useRef<HTMLDivElement>(null);
185185
const tabWidthRef = useRef<number>(TabDefaultWidth);
186186
const scrollableRef = useRef<boolean>(false);
187-
const updateStatusBannerRef = useRef<HTMLButtonElement>(null);
188-
const configErrorButtonRef = useRef<HTMLElement>(null);
189187
const prevAllLoadedRef = useRef<boolean>(false);
190188
const activeTabId = useAtomValue(env.atoms.staticTabId);
191189
const isFullScreen = useAtomValue(env.atoms.isFullScreen);
@@ -237,23 +235,21 @@ const TabBar = memo(({ workspace }: TabBarProps) => {
237235

238236
const tabbarWrapperWidth = tabbarWrapperRef.current.getBoundingClientRect().width;
239237
const windowDragLeftWidth = draggerLeftRef.current.getBoundingClientRect().width;
240-
const windowDragRightWidth = draggerRightRef.current?.getBoundingClientRect().width ?? 0;
238+
const rightContainerWidth = rightContainerRef.current?.getBoundingClientRect().width ?? 0;
241239
const addBtnWidth = addBtnRef.current.getBoundingClientRect().width;
242-
const updateStatusLabelWidth = updateStatusBannerRef.current?.getBoundingClientRect().width ?? 0;
243-
const configErrorWidth = configErrorButtonRef.current?.getBoundingClientRect().width ?? 0;
244240
const appMenuButtonWidth = appMenuButtonRef.current?.getBoundingClientRect().width ?? 0;
245241
const workspaceSwitcherWidth = workspaceSwitcherRef.current?.getBoundingClientRect().width ?? 0;
246242
const waveAIButtonWidth = waveAIButtonRef.current?.getBoundingClientRect().width ?? 0;
243+
const spacerMinWidth = 4;
247244

248245
const nonTabElementsWidth =
249246
windowDragLeftWidth +
250-
windowDragRightWidth +
247+
rightContainerWidth +
251248
addBtnWidth +
252-
updateStatusLabelWidth +
253-
configErrorWidth +
254249
appMenuButtonWidth +
255250
workspaceSwitcherWidth +
256-
waveAIButtonWidth;
251+
waveAIButtonWidth +
252+
spacerMinWidth;
257253
const spaceForTabs = tabbarWrapperWidth - nonTabElementsWidth;
258254

259255
const numberOfTabs = tabIds.length;
@@ -636,12 +632,6 @@ const TabBar = memo(({ workspace }: TabBarProps) => {
636632
}
637633
}
638634

639-
const addtabButtonDecl: IconButtonDecl = {
640-
elemtype: "iconbutton",
641-
icon: "plus",
642-
click: handleAddTab,
643-
title: "Add Tab",
644-
};
645635
return (
646636
<div ref={tabbarWrapperRef} className="tab-bar-wrapper">
647637
<div
@@ -693,12 +683,20 @@ const TabBar = memo(({ workspace }: TabBarProps) => {
693683
})}
694684
</div>
695685
</div>
696-
<IconButton className="add-tab" ref={addBtnRef} decl={addtabButtonDecl} />
697-
<div className="tab-bar-right">
698-
<UpdateStatusBanner ref={updateStatusBannerRef} />
699-
<ConfigErrorIcon buttonRef={configErrorButtonRef} />
686+
<button
687+
ref={addBtnRef}
688+
title="Add Tab"
689+
className="flex h-[22px] px-2 mb-1 items-center rounded-md box-border cursor-pointer hover:bg-hoverbg transition-colors text-[12px] text-secondary hover:text-primary"
690+
style={{ WebkitAppRegion: "no-drag" } as React.CSSProperties}
691+
onClick={handleAddTab}
692+
>
693+
<i className="fa fa-solid fa-plus" />
694+
</button>
695+
<div className="flex-1 min-w-[4px]" />
696+
<div ref={rightContainerRef} className="flex flex-row gap-1 items-end">
697+
<UpdateStatusBanner />
698+
<ConfigErrorIcon />
700699
<div
701-
ref={draggerRightRef}
702700
className="h-full shrink-0 z-window-drag"
703701
style={{ width: windowDragRightWidth, WebkitAppRegion: "drag" } as any}
704702
/>

frontend/app/tab/updatebanner.tsx

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
1-
import { Button } from "@/element/button";
1+
// Copyright 2026, Command Line Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import { Tooltip } from "@/element/tooltip";
25
import { atoms, getApi } from "@/store/global";
36
import { useAtomValue } from "jotai";
4-
import { forwardRef, memo, useEffect, useState } from "react";
7+
import { Download } from "lucide-react";
8+
import { memo, useEffect, useState } from "react";
59

6-
const UpdateStatusBannerComponent = forwardRef<HTMLButtonElement>((_, ref) => {
7-
let appUpdateStatus = useAtomValue(atoms.updaterStatusAtom);
8-
let [updateStatusMessage, setUpdateStatusMessage] = useState<string>();
10+
const UpdateStatusBannerComponent = () => {
11+
const appUpdateStatus = useAtomValue(atoms.updaterStatusAtom);
12+
const [updateStatusMessage, setUpdateStatusMessage] = useState<string>();
913
const [dismissBannerTimeout, setDismissBannerTimeout] = useState<NodeJS.Timeout>();
1014

1115
useEffect(() => {
1216
let message: string;
1317
let dismissBanner = false;
1418
switch (appUpdateStatus) {
1519
case "ready":
16-
message = "Update Available";
20+
message = "Update";
1721
break;
1822
case "downloading":
19-
message = "Downloading Update";
23+
message = "Downloading";
2024
break;
2125
case "installing":
22-
message = "Installing Update";
23-
break;
24-
case "error":
25-
message = "Updater Error: Try Checking Again";
26-
dismissBanner = true;
26+
message = "Installing";
2727
break;
2828
default:
2929
break;
@@ -51,19 +51,27 @@ const UpdateStatusBannerComponent = forwardRef<HTMLButtonElement>((_, ref) => {
5151
function onClick() {
5252
getApi().installAppUpdate();
5353
}
54-
if (updateStatusMessage) {
55-
return (
56-
<Button
57-
className="text-black bg-[var(--accent-color)] flex-[0_0_fit-content] !h-full !px-3 disabled:!opacity-[unset]"
58-
title={appUpdateStatus === "ready" ? "Click to Install Update" : updateStatusMessage}
59-
onClick={onClick}
60-
disabled={appUpdateStatus !== "ready"}
61-
ref={ref}
62-
>
63-
{updateStatusMessage}
64-
</Button>
65-
);
54+
55+
if (!updateStatusMessage) {
56+
return null;
6657
}
67-
});
6858

69-
export const UpdateStatusBanner = memo(UpdateStatusBannerComponent) as typeof UpdateStatusBannerComponent;
59+
const isReady = appUpdateStatus === "ready";
60+
const tooltipContent = isReady ? "Click to Install Update" : updateStatusMessage;
61+
62+
return (
63+
<Tooltip
64+
content={tooltipContent}
65+
placement="bottom"
66+
divOnClick={isReady ? onClick : undefined}
67+
divClassName={`flex items-center gap-1 px-2 mb-1 h-[22px] text-xs font-medium text-black bg-accent rounded-sm transition-all ${isReady ? "cursor-pointer hover:bg-[var(--button-green-border-color)]" : ""}`}
68+
divStyle={{ WebkitAppRegion: "no-drag" } as any}
69+
>
70+
<Download size={12} />
71+
{updateStatusMessage}
72+
</Tooltip>
73+
);
74+
};
75+
UpdateStatusBannerComponent.displayName = "UpdateStatusBannerComponent";
76+
77+
export const UpdateStatusBanner = memo(UpdateStatusBannerComponent);

0 commit comments

Comments
 (0)