Skip to content

Commit 879b0fa

Browse files
authored
Merge pull request #38 from david-ponc/feature/tooltip-in-slider
feat: tooltip in slider
2 parents 916f6b7 + 95addde commit 879b0fa

File tree

2 files changed

+66
-22
lines changed

2 files changed

+66
-22
lines changed

website/app/components/navbar/options.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useSearchParams } from "@remix-run/react";
33
import { Input } from "@/ui/input";
44
import { Slider } from "@/ui/slider";
55
import { iconSizeParamKey, searchParamKey } from "@/data/searchParams";
6+
import { useEffect, useState } from "react";
67

78
interface iSearchProps {
89
className?: string;
@@ -40,7 +41,9 @@ export const Search = (props: iSearchProps) => {
4041
// 📏 Icon Size Slider:
4142
export const IconSize = () => {
4243
const [searchParams, setSearchParams] = useSearchParams();
43-
const iconSizeValue = searchParams.get(iconSizeParamKey) || 45;
44+
const [iconSizeValue, setIconSizeValue] = useState(
45+
Number(searchParams.get(iconSizeParamKey)) || 45,
46+
);
4447

4548
const handleChange = (value: number[]) => {
4649
const newSearchParams = new URLSearchParams(searchParams);
@@ -52,11 +55,15 @@ export const IconSize = () => {
5255
setSearchParams(newSearchParams);
5356
};
5457

58+
useEffect(() => {
59+
handleChange([iconSizeValue]);
60+
}, [iconSizeValue]);
61+
5562
return (
5663
<Slider
5764
title="Icon Size"
58-
defaultValue={[Number(iconSizeValue)]}
59-
onValueChange={(value) => handleChange(value)}
65+
value={[Number(iconSizeValue)]}
66+
onValueChange={(value) => setIconSizeValue(value[0])}
6067
max={70}
6168
min={20}
6269
step={1}

website/app/ui/slider.tsx

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,66 @@
22
import * as SliderPrimitive from "@radix-ui/react-slider";
33

44
import { cn } from "@/utils";
5-
import { forwardRef } from "react";
5+
import { forwardRef, useEffect, useState } from "react";
6+
import {
7+
Tooltip,
8+
TooltipContent,
9+
TooltipProvider,
10+
TooltipTrigger,
11+
} from "./tooltip";
612

713
const Slider = forwardRef<
814
React.ElementRef<typeof SliderPrimitive.Root>,
915
React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>
10-
>(({ className, ...props }, ref) => (
11-
<SliderPrimitive.Root
12-
ref={ref}
13-
className={cn(
14-
"relative flex w-full touch-none select-none items-center",
15-
className,
16-
)}
17-
{...props}
18-
>
19-
<SliderPrimitive.Track className="relative h-1.5 w-full grow overflow-hidden rounded-full bg-zinc-900/20 dark:bg-zinc-800">
20-
<SliderPrimitive.Range className="absolute h-full bg-zinc-900 dark:bg-zinc-600" />
21-
</SliderPrimitive.Track>
22-
<SliderPrimitive.Thumb
23-
title="Increase or decrease the size"
24-
className="block h-4 w-4 rounded-full border border-zinc-200 border-zinc-900/50 bg-white shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-zinc-950 disabled:pointer-events-none disabled:opacity-50 dark:border-zinc-50/50 dark:border-zinc-800 dark:bg-zinc-500 dark:focus-visible:ring-zinc-600"
25-
/>
26-
</SliderPrimitive.Root>
27-
));
16+
>(({ className, ...props }, ref) => {
17+
const [showTooltipState, setShowTooltipState] = useState(false);
18+
const handlePointerDown = () => {
19+
setShowTooltipState(true);
20+
};
21+
22+
const handlePointerUp = () => {
23+
setShowTooltipState(false);
24+
};
25+
26+
useEffect(() => {
27+
document.addEventListener("pointerup", handlePointerUp);
28+
return () => {
29+
document.removeEventListener("pointerup", handlePointerUp);
30+
};
31+
}, []);
32+
33+
return (
34+
<SliderPrimitive.Root
35+
ref={ref}
36+
className={cn(
37+
"relative flex w-full touch-none select-none items-center",
38+
className,
39+
)}
40+
{...props}
41+
>
42+
<SliderPrimitive.Track className="relative h-1.5 w-full grow overflow-hidden rounded-full bg-zinc-900/20 dark:bg-zinc-800">
43+
<SliderPrimitive.Range className="absolute h-full bg-zinc-900 dark:bg-zinc-600" />
44+
</SliderPrimitive.Track>
45+
<TooltipProvider>
46+
<Tooltip delayDuration={0} open={showTooltipState}>
47+
<TooltipTrigger asChild>
48+
<SliderPrimitive.Thumb
49+
title="Increase or decrease the size"
50+
onMouseEnter={() => setShowTooltipState(true)}
51+
onMouseLeave={() => setShowTooltipState(false)}
52+
onFocus={() => setShowTooltipState(true)}
53+
onBlur={() => setShowTooltipState(false)}
54+
className="block h-4 w-4 rounded-full border border-zinc-200 border-zinc-900/50 bg-white shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-zinc-950 disabled:pointer-events-none disabled:opacity-50 dark:border-zinc-50/50 dark:border-zinc-800 dark:bg-zinc-500 dark:focus-visible:ring-zinc-600"
55+
/>
56+
</TooltipTrigger>
57+
<TooltipContent align="center" side="top" className="text-center">
58+
{props.value?.at(0)}
59+
</TooltipContent>
60+
</Tooltip>
61+
</TooltipProvider>
62+
</SliderPrimitive.Root>
63+
);
64+
});
2865
Slider.displayName = SliderPrimitive.Root.displayName;
2966

3067
export { Slider };

0 commit comments

Comments
 (0)