mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-20 23:59:55 +00:00
add update available icon
This commit is contained in:
74
client/ui/frontend/src/components/Tooltip.tsx
Normal file
74
client/ui/frontend/src/components/Tooltip.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
import { ReactNode, useRef, useState } from "react";
|
||||
import * as RTooltip from "@radix-ui/react-tooltip";
|
||||
import { cn } from "@/lib/cn";
|
||||
|
||||
type Props = {
|
||||
content: ReactNode;
|
||||
children: ReactNode;
|
||||
side?: RTooltip.TooltipContentProps["side"];
|
||||
align?: RTooltip.TooltipContentProps["align"];
|
||||
delayDuration?: number;
|
||||
sideOffset?: number;
|
||||
interactive?: boolean;
|
||||
keepOpenOnClick?: boolean;
|
||||
};
|
||||
|
||||
export const Tooltip = ({
|
||||
content,
|
||||
children,
|
||||
side = "bottom",
|
||||
align = "center",
|
||||
delayDuration = 200,
|
||||
sideOffset = 6,
|
||||
interactive = false,
|
||||
keepOpenOnClick = true,
|
||||
}: Props) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const hoveringRef = useRef(false);
|
||||
|
||||
const handleOpenChange = (next: boolean) => {
|
||||
if (!next && keepOpenOnClick && hoveringRef.current) return;
|
||||
setOpen(next);
|
||||
};
|
||||
|
||||
return (
|
||||
<RTooltip.Provider
|
||||
delayDuration={delayDuration}
|
||||
disableHoverableContent={!interactive}
|
||||
>
|
||||
<RTooltip.Root open={open} onOpenChange={handleOpenChange}>
|
||||
<RTooltip.Trigger
|
||||
asChild
|
||||
onPointerEnter={() => {
|
||||
hoveringRef.current = true;
|
||||
}}
|
||||
onPointerLeave={() => {
|
||||
hoveringRef.current = false;
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</RTooltip.Trigger>
|
||||
<RTooltip.Portal>
|
||||
<RTooltip.Content
|
||||
side={side}
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
onPointerDownOutside={
|
||||
interactive ? undefined : (e) => e.preventDefault()
|
||||
}
|
||||
className={cn(
|
||||
"z-50 select-none rounded-md border border-nb-gray-850 bg-nb-gray-900 px-2 py-1",
|
||||
"text-xs text-nb-gray-100 shadow-lg",
|
||||
"data-[state=delayed-open]:animate-in data-[state=closed]:animate-out",
|
||||
"data-[state=closed]:fade-out-0 data-[state=delayed-open]:fade-in-0",
|
||||
!interactive && "pointer-events-none",
|
||||
)}
|
||||
>
|
||||
{content}
|
||||
</RTooltip.Content>
|
||||
</RTooltip.Portal>
|
||||
</RTooltip.Root>
|
||||
</RTooltip.Provider>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ComponentType, forwardRef } from "react";
|
||||
import { ComponentType, ReactNode, forwardRef } from "react";
|
||||
import * as Tabs from "@radix-ui/react-tabs";
|
||||
import { LucideProps } from "lucide-react";
|
||||
import { cn } from "@/lib/cn";
|
||||
@@ -33,11 +33,12 @@ type TriggerProps = Tabs.TabsTriggerProps & {
|
||||
icon: ComponentType<LucideProps>;
|
||||
title: string;
|
||||
iconSize?: number;
|
||||
adornment?: ReactNode;
|
||||
};
|
||||
|
||||
const Trigger = forwardRef<HTMLButtonElement, TriggerProps>(
|
||||
function VerticalTabsTrigger(
|
||||
{ icon: Icon, title, iconSize = 16, className, ...props },
|
||||
{ icon: Icon, title, iconSize = 16, adornment, className, ...props },
|
||||
ref,
|
||||
) {
|
||||
return (
|
||||
@@ -67,6 +68,7 @@ const Trigger = forwardRef<HTMLButtonElement, TriggerProps>(
|
||||
>
|
||||
{title}
|
||||
</h2>
|
||||
{adornment && <div className={"ml-auto mr-2 shrink-0"}>{adornment}</div>}
|
||||
</Tabs.Trigger>
|
||||
);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user