Skip to content

Commit

Permalink
feat: Tooltip component
Browse files Browse the repository at this point in the history
  • Loading branch information
BrickheadJohnny committed Nov 28, 2024
1 parent 7ac01cb commit 7e25c56
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@radix-ui/react-switch": "^1.1.1",
"@radix-ui/react-toggle": "^1.1.0",
"@radix-ui/react-toggle-group": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.4",
"@t3-oss/env-nextjs": "^0.11.1",
"@tailwindcss/typography": "^0.5.15",
"@tanstack/react-query": "^5.60.2",
Expand Down
80 changes: 80 additions & 0 deletions src/components/ui/Tooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"use client";

import { cn } from "@/lib/cssUtils";
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
import { type VariantProps, cva } from "class-variance-authority";
import {
type ComponentPropsWithoutRef,
type ElementRef,
type FC,
forwardRef,
} from "react";

const tooltipVariants = cva(
"fade-in-0 zoom-in-95 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 z-50 max-w-sm animate-in px-3 py-1.5 text-center font-medium font-sans text-sm shadow-md data-[state=closed]:animate-out",
{
variants: {
variant: {
tooltip:
"bg-tooltip text-tooltip-foreground rounded-xl [&_svg.tooltip-arrow]:fill-tooltip",
popover:
"bg-popover text-popover-foreground rounded-lg outline outline-1 outline-border [&_svg.tooltip-arrow]:fill-popover [&_svg.tooltip-arrow]:[filter:drop-shadow(1px_0_0_hsl(var(--border)))_drop-shadow(-1px_0_0_hsl(var(--border)))_drop-shadow(0_1px_0_hsl(var(--border)))]",
},
},
defaultVariants: {
variant: "tooltip",
},
},
);

const TooltipProvider = TooltipPrimitive.Provider;

const Tooltip: FC<ComponentPropsWithoutRef<typeof TooltipPrimitive.Root>> = ({
...props
}) => <TooltipPrimitive.Root delayDuration={0} {...props} />;

const TooltipTrigger = forwardRef<
ElementRef<typeof TooltipPrimitive.Trigger>,
ComponentPropsWithoutRef<typeof TooltipPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<TooltipPrimitive.Trigger
ref={ref}
className={cn(
"outline-none focus-visible:ring-4 focus-visible:ring-ring",
className,
)}
{...props}
>
{children}
</TooltipPrimitive.Trigger>
));

export interface TooltipContentProps
extends ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>,
VariantProps<typeof tooltipVariants> {}

const TooltipContent = forwardRef<
ElementRef<typeof TooltipPrimitive.Content>,
TooltipContentProps
>(({ className, sideOffset = 4, variant, children, ...props }, ref) => (
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(tooltipVariants({ variant, className }))}
{...props}
>
{children}
<TooltipPrimitive.Arrow className="tooltip-arrow" />
</TooltipPrimitive.Content>
));
TooltipContent.displayName = TooltipPrimitive.Content.displayName;

const TooltipPortal = TooltipPrimitive.Portal;

export {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
TooltipPortal,
};
40 changes: 40 additions & 0 deletions src/stories/Tooltip.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Button } from "@/components/ui/Button";
import {
Tooltip,
TooltipContent,
type TooltipContentProps,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/Tooltip";
import type { Meta, StoryObj } from "@storybook/react";

const TooltipExample = (tooltipContentProps: TooltipContentProps) => (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline" size="sm">
Hover me!
</Button>
</TooltipTrigger>
<TooltipContent {...tooltipContentProps}>
<p>This is a tooltip!</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);

const meta: Meta<typeof TooltipExample> = {
title: "Design system/Tooltip",
component: TooltipExample,
};

export default meta;

type Story = StoryObj<typeof TooltipExample>;

export const Default: Story = {};
export const Popover: Story = {
args: {
variant: "popover",
},
};
10 changes: 10 additions & 0 deletions src/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ html {
--gray-800: #27272a;
--gray-900: #18181b;

--black: #000;
--white: #fff;

--blackAlpha: rgba(0, 0, 0, 0.06);
Expand All @@ -113,6 +114,12 @@ html {
--input-border-invalid: var(--red-500);
--input-background: var(--white);

--popover: var(--card);
--popover-foreground: var(--foreground);

--tooltip: var(--black);
--tooltip-foreground: var(--gray-100);

--button-primary: var(--indigo-500);
--button-primary-hover: var(--indigo-600);
--button-primary-active: var(--indigo-700);
Expand Down Expand Up @@ -167,6 +174,9 @@ html {
--input-border-invalid: var(--red-300);
--input-background: var(--blackAlpha-hard);

--tooltip: var(--gray-300);
--tooltip-foreground: var(--gray-800);

--button-primary: var(--indigo-500);
--button-primary-hover: var(--indigo-400);
--button-primary-active: var(--indigo-300);
Expand Down
8 changes: 8 additions & 0 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ const config = {
invalid: "var(--input-border-invalid)"
},
},
tooltip: {
DEFAULT: "var(--tooltip)",
foreground: "var(--tooltip-foreground)",
},
popover: {
DEFAULT: "var(--popover)",
foreground: "var(--popover-foreground)",
},
// Using these in our Toggle component
button: {
primary: {
Expand Down

0 comments on commit 7e25c56

Please sign in to comment.