refactor: integrate Tooltip component and enhance LaunchWindow with tooltips

This commit is contained in:
Prayas Lashkari
2026-03-12 22:14:44 -04:00
parent 066832a3bd
commit 151a3b2902
4 changed files with 115 additions and 36 deletions
+1
View File
@@ -31,6 +31,7 @@
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-toggle": "^1.1.10",
"@radix-ui/react-toggle-group": "^1.1.11",
"@radix-ui/react-tooltip": "^1.2.8",
"@types/gif.js": "^0.2.5",
"@uiw/color-convert": "^2.9.2",
"@uiw/react-color-block": "^2.9.2",
+24 -19
View File
@@ -1,6 +1,7 @@
import { useEffect, useState } from "react";
import { LaunchWindow } from "./components/launch/LaunchWindow";
import { SourceSelector } from "./components/launch/SourceSelector";
import { TooltipProvider } from "./components/ui/tooltip";
import { ShortcutsConfigDialog } from "./components/video-editor/ShortcutsConfigDialog";
import VideoEditor from "./components/video-editor/VideoEditor";
import { ShortcutsProvider } from "./contexts/ShortcutsContext";
@@ -25,23 +26,27 @@ export default function App() {
});
}, []);
switch (windowType) {
case "hud-overlay":
return <LaunchWindow />;
case "source-selector":
return <SourceSelector />;
case "editor":
return (
<ShortcutsProvider>
<VideoEditor />
<ShortcutsConfigDialog />
</ShortcutsProvider>
);
default:
return (
<div className="w-full h-full bg-background text-foreground">
<h1>Openscreen</h1>
</div>
);
}
const content = (() => {
switch (windowType) {
case "hud-overlay":
return <LaunchWindow />;
case "source-selector":
return <SourceSelector />;
case "editor":
return (
<ShortcutsProvider>
<VideoEditor />
<ShortcutsConfigDialog />
</ShortcutsProvider>
);
default:
return (
<div className="w-full h-full bg-background text-foreground">
<h1>Openscreen</h1>
</div>
);
}
})();
return <TooltipProvider>{content}</TooltipProvider>;
}
+20 -17
View File
@@ -13,6 +13,7 @@ import {
} from "react-icons/md";
import { RxDragHandleDots2 } from "react-icons/rx";
import { ChevronDown } from "lucide-react";
import { Tooltip } from "../ui/tooltip";
import { useAudioLevelMeter } from "../../hooks/useAudioLevelMeter";
import { useMicrophoneDevices } from "../../hooks/useMicrophoneDevices";
import { useScreenRecorder } from "../../hooks/useScreenRecorder";
@@ -20,7 +21,7 @@ import { formatTimePadded } from "../../utils/timeUtils";
import { AudioLevelMeter } from "../ui/audio-level-meter";
import styles from "./LaunchWindow.module.css";
const ICON_SIZE = 18;
const ICON_SIZE = 20;
const ICON_CONFIG = {
drag: { icon: RxDragHandleDots2, size: ICON_SIZE },
@@ -278,24 +279,26 @@ export function LaunchWindow() {
</button>
{/* Open video file */}
<button
className={`${hudIconBtnClasses} ${styles.electronNoDrag}`}
onClick={openVideoFile}
disabled={recording}
title="Open video file"
>
{getIcon("videoFile", "text-white/60")}
</button>
<Tooltip content="Open video file">
<button
className={`${hudIconBtnClasses} ${styles.electronNoDrag}`}
onClick={openVideoFile}
disabled={recording}
>
{getIcon("videoFile", "text-white/60")}
</button>
</Tooltip>
{/* Open project */}
<button
className={`${hudIconBtnClasses} ${styles.electronNoDrag}`}
onClick={openProjectFile}
disabled={recording}
title="Open project"
>
{getIcon("folder", "text-white/60")}
</button>
<Tooltip content="Open project">
<button
className={`${hudIconBtnClasses} ${styles.electronNoDrag}`}
onClick={openProjectFile}
disabled={recording}
>
{getIcon("folder", "text-white/60")}
</button>
</Tooltip>
{/* Window controls */}
<div className={`flex items-center gap-0.5 ${styles.electronNoDrag}`}>
+70
View File
@@ -0,0 +1,70 @@
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
import * as React from "react";
import { cn } from "@/lib/utils";
function TooltipProvider({
delayDuration = 200,
...props
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
return (
<TooltipPrimitive.Provider
data-slot="tooltip-provider"
delayDuration={delayDuration}
{...props}
/>
);
}
function TooltipRoot({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) {
return <TooltipPrimitive.Root data-slot="tooltip" {...props} />;
}
function TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
}
function TooltipContent({
className,
sideOffset = 6,
...props
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
return (
<TooltipPrimitive.Portal>
<TooltipPrimitive.Content
data-slot="tooltip-content"
sideOffset={sideOffset}
className={cn(
"px-2 py-1 text-[11px] leading-none text-white/90 bg-black/85 border border-white/10 rounded-md z-50",
"animate-in fade-in-0 zoom-in-95",
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
className,
)}
{...props}
/>
</TooltipPrimitive.Portal>
);
}
function Tooltip({
children,
content,
side,
className,
}: {
children: React.ReactNode;
content: React.ReactNode;
side?: "top" | "right" | "bottom" | "left";
className?: string;
}) {
return (
<TooltipRoot>
<TooltipTrigger asChild>{children}</TooltipTrigger>
<TooltipContent side={side} className={className}>
{content}
</TooltipContent>
</TooltipRoot>
);
}
export { TooltipProvider, TooltipRoot, TooltipTrigger, TooltipContent, Tooltip };