Skip to content

Commit ca4c4bf

Browse files
committed
🤖 fix: threshold slider no longer blocks token meter tooltip
The threshold slider was covering the entire bar container, intercepting all mouse events and preventing the token meter tooltip from showing. Fix: Use pointer-events: none on the container and only capture events in a small drag zone around the indicator. This allows the tooltip to show when hovering elsewhere on the bar. --- _Generated with `mux`_
1 parent 055145c commit ca4c4bf

File tree

3 files changed

+52
-16
lines changed

3 files changed

+52
-16
lines changed

src/browser/components/RightSidebar/ThresholdSlider.tsx

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -174,15 +174,38 @@ export const ThresholdSlider: React.FC<ThresholdSliderProps> = ({ config, orient
174174
const color = isEnabled ? "var(--color-plan-mode)" : "var(--color-muted)";
175175
const tooltipText = getTooltipText(config.threshold, orientation);
176176

177-
// Container styles
177+
// Container styles - covers the full bar area for drag handling
178+
// Uses pointer-events: none by default, only the indicator handle has pointer-events: auto
179+
// This allows the token meter tooltip to work when hovering elsewhere on the bar
178180
const containerStyle: React.CSSProperties = {
179181
position: "absolute",
180-
cursor: isHorizontal ? "ew-resize" : "ns-resize",
181182
top: 0,
182183
bottom: 0,
183184
left: 0,
184185
right: 0,
185186
zIndex: 50,
187+
pointerEvents: "none", // Let events pass through to tooltip beneath
188+
};
189+
190+
// Drag handle around the indicator - this captures mouse events
191+
const DRAG_ZONE_SIZE = 16; // pixels on each side of the indicator
192+
const handleStyle: React.CSSProperties = {
193+
position: "absolute",
194+
cursor: isHorizontal ? "ew-resize" : "ns-resize",
195+
pointerEvents: "auto", // Only this element captures events
196+
...(isHorizontal
197+
? {
198+
left: `calc(${config.threshold}% - ${DRAG_ZONE_SIZE}px)`,
199+
width: DRAG_ZONE_SIZE * 2,
200+
top: 0,
201+
bottom: 0,
202+
}
203+
: {
204+
top: `calc(${config.threshold}% - ${DRAG_ZONE_SIZE}px)`,
205+
height: DRAG_ZONE_SIZE * 2,
206+
left: 0,
207+
right: 0,
208+
}),
186209
};
187210

188211
// Indicator positioning - use transform for centering on both axes
@@ -215,15 +238,17 @@ export const ThresholdSlider: React.FC<ThresholdSliderProps> = ({ config, orient
215238
const containerRect = containerRef.current?.getBoundingClientRect();
216239

217240
return (
218-
<div
219-
ref={containerRef}
220-
style={containerStyle}
221-
onMouseDown={handleMouseDown}
222-
onMouseEnter={() => setIsHovered(true)}
223-
onMouseLeave={() => setIsHovered(false)}
224-
// Horizontal uses native title (simpler, no clipping issues with wide tooltips)
225-
title={isHorizontal ? tooltipText : undefined}
226-
>
241+
<div ref={containerRef} style={containerStyle}>
242+
{/* Drag handle - captures mouse events in a small zone around the indicator */}
243+
<div
244+
style={handleStyle}
245+
onMouseDown={handleMouseDown}
246+
onMouseEnter={() => setIsHovered(true)}
247+
onMouseLeave={() => setIsHovered(false)}
248+
// Horizontal uses native title (simpler, no clipping issues with wide tooltips)
249+
title={isHorizontal ? tooltipText : undefined}
250+
/>
251+
227252
{/* Visual indicator - pointer events disabled */}
228253
<div style={indicatorStyle}>
229254
<Triangle direction={isHorizontal ? "down" : "right"} color={color} />

src/browser/hooks/useAutoScroll.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,18 @@ export function useAutoScroll() {
3838
}, []); // No deps - ref ensures we always check current value
3939

4040
const jumpToBottom = useCallback(() => {
41-
if (contentRef.current) {
42-
contentRef.current.scrollTop = contentRef.current.scrollHeight;
43-
setAutoScroll(true);
44-
}
41+
if (!contentRef.current) return;
42+
43+
// Double RAF: First frame for DOM updates (async highlighting, image loads),
44+
// second frame to scroll after layout is complete
45+
requestAnimationFrame(() => {
46+
requestAnimationFrame(() => {
47+
if (contentRef.current) {
48+
contentRef.current.scrollTop = contentRef.current.scrollHeight;
49+
}
50+
});
51+
});
52+
setAutoScroll(true);
4553
}, []);
4654

4755
const handleScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {

src/cli/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ if (subcommand === "run") {
4242
process.argv.splice(2, 1);
4343
// eslint-disable-next-line @typescript-eslint/no-require-imports
4444
require("./api");
45-
} else if (subcommand === "desktop" || (isElectron && (subcommand === undefined || isElectronLaunchArg))) {
45+
} else if (
46+
subcommand === "desktop" ||
47+
(isElectron && (subcommand === undefined || isElectronLaunchArg))
48+
) {
4649
// Explicit `mux desktop`, or Electron runtime with no subcommand / Electron launch args
4750
launchDesktop();
4851
} else {

0 commit comments

Comments
 (0)