Skip to content

Commit d34d2da

Browse files
committed
upd: added proper tooltips
1 parent a545cf4 commit d34d2da

File tree

5 files changed

+119
-87
lines changed

5 files changed

+119
-87
lines changed

client/app/components/copy-button.tsx

+20-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Check, Copy } from "lucide-react";
22
import { useState } from "react";
33
import { Button } from "~/components/ui/button";
4+
import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip";
45

56
const CopyButton = ({ text }: { text: any }) => {
67
const [copied, setCopied] = useState(false);
@@ -13,18 +14,25 @@ const CopyButton = ({ text }: { text: any }) => {
1314
};
1415

1516
return (
16-
<Button
17-
onClick={handleCopy}
18-
variant="ghost"
19-
size="icon"
20-
className="flex items-center space-x-2 text-muted-foreground"
21-
>
22-
{copied ? (
23-
<Check className="size-4" />
24-
) : (
25-
<Copy className="size-4" />
26-
)}
27-
</Button>
17+
<Tooltip>
18+
<TooltipTrigger asChild>
19+
<Button
20+
onClick={handleCopy}
21+
variant="ghost"
22+
size="icon"
23+
className="flex items-center space-x-2 text-muted-foreground"
24+
>
25+
{copied ? (
26+
<Check className="size-4" />
27+
) : (
28+
<Copy className="size-4" />
29+
)}
30+
</Button>
31+
</TooltipTrigger>
32+
<TooltipContent side="bottom">
33+
<p>Copy</p>
34+
</TooltipContent>
35+
</Tooltip>
2836
);
2937
};
3038

client/app/components/ui/button.tsx

+49-48
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,58 @@
1-
import * as React from "react"
2-
import { Slot } from "@radix-ui/react-slot"
3-
import { cva, type VariantProps } from "class-variance-authority"
1+
import * as React from "react";
2+
import { Slot } from "@radix-ui/react-slot";
3+
import { cva, type VariantProps } from "class-variance-authority";
44

5-
import { cn } from "~/lib/utils"
5+
import { cn } from "~/lib/utils";
66

77
const buttonVariants = cva(
8-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
9-
{
10-
variants: {
11-
variant: {
12-
default:
13-
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
14-
destructive:
15-
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
16-
outline:
17-
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
18-
secondary:
19-
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
20-
ghost: "hover:bg-accent hover:text-accent-foreground",
21-
link: "text-primary underline-offset-4 hover:underline",
22-
},
23-
size: {
24-
default: "h-9 px-4 py-2",
25-
sm: "h-8 rounded-md px-3 text-xs",
26-
lg: "h-10 rounded-md px-8",
27-
icon: "size-[30px] rounded-md",
28-
},
29-
},
30-
defaultVariants: {
31-
variant: "default",
32-
size: "default",
33-
},
34-
}
35-
)
8+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
9+
{
10+
variants: {
11+
variant: {
12+
default:
13+
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
14+
destructive:
15+
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
16+
outline:
17+
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
18+
secondary:
19+
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
20+
ghost: "hover:bg-accent hover:text-accent-foreground",
21+
link: "text-primary underline-offset-4 hover:underline",
22+
},
23+
size: {
24+
default: "h-9 px-4 py-2",
25+
sm: "h-8 rounded-md px-3 text-xs",
26+
lg: "h-10 rounded-md px-8",
27+
icon: "size-[30px] rounded-md",
28+
},
29+
},
30+
defaultVariants: {
31+
variant: "default",
32+
size: "default",
33+
},
34+
}
35+
);
3636

3737
export interface ButtonProps
38-
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
39-
VariantProps<typeof buttonVariants> {
40-
asChild?: boolean
38+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
39+
VariantProps<typeof buttonVariants> {
40+
asChild?: boolean;
4141
}
4242

4343
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
44-
({ className, variant, size, asChild = false, ...props }, ref) => {
45-
const Comp = asChild ? Slot : "button"
46-
return (
47-
<Comp
48-
className={cn(buttonVariants({ variant, size, className }))}
49-
ref={ref}
50-
{...props}
51-
/>
52-
)
53-
}
54-
)
55-
Button.displayName = "Button"
44+
({ className, variant, size, asChild = false, ...props }, ref) => {
45+
const Comp = asChild ? Slot : "button";
46+
return (
47+
<Comp
48+
type="button"
49+
className={cn(buttonVariants({ variant, size, className }))}
50+
ref={ref}
51+
{...props}
52+
/>
53+
);
54+
}
55+
);
56+
Button.displayName = "Button";
5657

57-
export { Button, buttonVariants }
58+
export { Button, buttonVariants };
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
1-
import { DotSquare, Ellipsis, StopCircle, Volume2 } from "lucide-react";
1+
import { Ellipsis, StopCircle, Volume2 } from "lucide-react";
22
import { Button } from "../button";
33
import { useMutation } from "@tanstack/react-query";
44
import { useState } from "react";
55
import { apiClient } from "~/lib/api";
6+
import { Tooltip, TooltipTrigger, TooltipContent } from "../tooltip";
67

7-
export default function ChatTtsButton({ agentId, text }: { agentId: string; text: string }) {
8+
export default function ChatTtsButton({
9+
agentId,
10+
text,
11+
}: {
12+
agentId: string;
13+
text: string;
14+
}) {
815
const [playing, setPlaying] = useState<boolean>(false);
916
const mutation = useMutation({
1017
mutationKey: ["tts", text],
11-
mutationFn: () => apiClient.speak(agentId, text),
12-
onSuccess: () => {
18+
mutationFn: () => apiClient.speak(agentId, ""),
19+
onSuccess: (data) => {
20+
console.log(data);
1321
setPlaying(true);
1422
},
23+
onError: (e) => {
24+
console.error(e.message);
25+
},
1526
});
1627

1728
const execute = () => {
@@ -24,20 +35,29 @@ export default function ChatTtsButton({ agentId, text }: { agentId: string; text
2435
};
2536

2637
const iconClass = "text-muted-foreground size-4";
38+
2739
return (
28-
<Button
29-
size="icon"
30-
variant="ghost"
31-
onClick={() => execute()}
32-
disabled={mutation?.isPending}
33-
>
34-
{mutation?.isPending ? (
35-
<Ellipsis className={iconClass} />
36-
) : playing ? (
37-
<StopCircle className={iconClass} />
38-
) : (
39-
<Volume2 className={iconClass} />
40-
)}
41-
</Button>
40+
<Tooltip>
41+
<TooltipTrigger asChild>
42+
<Button
43+
size="icon"
44+
variant="ghost"
45+
type="button"
46+
onClick={() => execute()}
47+
disabled={mutation?.isPending}
48+
>
49+
{mutation?.isPending ? (
50+
<Ellipsis className={iconClass} />
51+
) : playing ? (
52+
<StopCircle className={iconClass} />
53+
) : (
54+
<Volume2 className={iconClass} />
55+
)}
56+
</Button>
57+
</TooltipTrigger>
58+
<TooltipContent side="bottom">
59+
<p>Read aloud</p>
60+
</TooltipContent>
61+
</Tooltip>
4262
);
4363
}

client/app/components/ui/tooltip.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const TooltipContent = React.forwardRef<
1818
ref={ref}
1919
sideOffset={sideOffset}
2020
className={cn(
21-
"z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground 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 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
21+
"z-50 overflow-hidden select-none rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground 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 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
2222
className
2323
)}
2424
{...props}

client/app/root.tsx

+11-8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import type { LinksFunction } from "@remix-run/node";
1515

1616
import "./tailwind.css";
1717
import { AppSidebar } from "./components/app-sidebar";
18+
import { TooltipProvider } from "./components/ui/tooltip";
1819

1920
export const links: LinksFunction = () => [
2021
{ rel: "preconnect", href: "https://fonts.googleapis.com" },
@@ -51,14 +52,16 @@ export function Layout({ children }: { children: React.ReactNode }) {
5152
</head>
5253
<QueryClientProvider client={queryClient}>
5354
<body>
54-
<SidebarProvider>
55-
<AppSidebar />
56-
<SidebarInset>
57-
<div className="flex flex-1 flex-col gap-4 size-full">
58-
{children}
59-
</div>
60-
</SidebarInset>
61-
</SidebarProvider>
55+
<TooltipProvider delayDuration={0}>
56+
<SidebarProvider>
57+
<AppSidebar />
58+
<SidebarInset>
59+
<div className="flex flex-1 flex-col gap-4 size-full">
60+
{children}
61+
</div>
62+
</SidebarInset>
63+
</SidebarProvider>
64+
</TooltipProvider>
6265
<Scripts />
6366
<ScrollRestoration />
6467
</body>

0 commit comments

Comments
 (0)