Openstatus www.openstatus.dev
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

Show tooltip for disabled button (#279)

* add tooltip content to `Create` button

This will show a tooltip when the button is disabled

* return TooltipContent for disabled button

* format with prettier

* show tooltip on disabled button

* revert to default shadcn code for component

* add disabled button with tooltip component

* use disabled button with tooltip component

* add `pointer-events-none` for disabled button

* render button within a span in tooltip trigger

* add incoming `className` prop to `cn` helper

authored by

Kelvin Amoaba and committed by
GitHub
8eb62bd0 80fffdbe

+61 -6
+7 -3
apps/web/src/app/app/(dashboard)/[workspaceSlug]/monitors/page.tsx
··· 7 7 import { Header } from "@/components/dashboard/header"; 8 8 import { Limit } from "@/components/dashboard/limit"; 9 9 import { Badge } from "@/components/ui/badge"; 10 - import { Button } from "@/components/ui/button"; 10 + import { ButtonWithDisableTooltip } from "@/components/ui/button-with-disable-tooltip"; 11 11 import { cn } from "@/lib/utils"; 12 12 import { api } from "@/trpc/server"; 13 13 import { ActionButton } from "./_components/action-button"; ··· 32 32 return ( 33 33 <div className="grid gap-6 md:grid-cols-2 md:gap-8"> 34 34 <Header title="Monitors" description="Overview of all your monitors."> 35 - <Button asChild={!isLimit} disabled={isLimit}> 35 + <ButtonWithDisableTooltip 36 + tooltip="You reached the limits" 37 + asChild={!isLimit} 38 + disabled={isLimit} 39 + > 36 40 <Link href="./monitors/edit">Create</Link> 37 - </Button> 41 + </ButtonWithDisableTooltip> 38 42 </Header> 39 43 {Boolean(monitors?.length) ? ( 40 44 monitors?.map((monitor, index) => (
+7 -2
apps/web/src/app/app/(dashboard)/[workspaceSlug]/status-pages/page.tsx
··· 8 8 import { Limit } from "@/components/dashboard/limit"; 9 9 import { Badge } from "@/components/ui/badge"; 10 10 import { Button } from "@/components/ui/button"; 11 + import { ButtonWithDisableTooltip } from "@/components/ui/button-with-disable-tooltip"; 11 12 import { cn } from "@/lib/utils"; 12 13 import { api } from "@/trpc/server"; 13 14 import { ActionButton } from "./_components/action-button"; ··· 44 45 title="Status Page" 45 46 description="Overview of all your status pages." 46 47 > 47 - <Button asChild={!disableButton} disabled={disableButton}> 48 + <ButtonWithDisableTooltip 49 + tooltip="You reached the limits" 50 + asChild={!disableButton} 51 + disabled={disableButton} 52 + > 48 53 <Link href="./status-pages/edit">Create</Link> 49 - </Button> 54 + </ButtonWithDisableTooltip> 50 55 </Header> 51 56 {Boolean(pages?.length) ? ( 52 57 pages?.map((page, index) => (
+45
apps/web/src/components/ui/button-with-disable-tooltip.tsx
··· 1 + import { cn } from "@/lib/utils"; 2 + import { Button } from "./button"; 3 + import type { ButtonProps } from "./button"; 4 + import { 5 + Tooltip, 6 + TooltipContent, 7 + TooltipProvider, 8 + TooltipTrigger, 9 + } from "./tooltip"; 10 + 11 + interface ButtonWithDisableTooltipProps extends ButtonProps { 12 + tooltip: string; 13 + } 14 + 15 + export const ButtonWithDisableTooltip = ({ 16 + tooltip, 17 + disabled, 18 + className, 19 + ...props 20 + }: ButtonWithDisableTooltipProps) => { 21 + const ButtonComponent = ( 22 + <Button 23 + {...props} 24 + disabled={disabled} 25 + className={cn(className, disabled && "pointer-events-none")} 26 + /> 27 + ); 28 + 29 + if (disabled) { 30 + // If the button is disabled, we wrap it in a tooltip since 31 + // we don't want to show the tooltip if the button is enabled. 32 + return ( 33 + <TooltipProvider> 34 + <Tooltip> 35 + <TooltipTrigger asChild> 36 + <span tabIndex={0}>{ButtonComponent}</span> 37 + </TooltipTrigger> 38 + <TooltipContent>{tooltip}</TooltipContent> 39 + </Tooltip> 40 + </TooltipProvider> 41 + ); 42 + } 43 + 44 + return ButtonComponent; 45 + };
+2 -1
apps/web/src/components/ui/button.tsx
··· 42 42 } 43 43 44 44 const Button = React.forwardRef<HTMLButtonElement, ButtonProps>( 45 - ({ className, variant, size, asChild = false, ...props }, ref) => { 45 + ({ className, variant, size, asChild = false, disabled, ...props }, ref) => { 46 46 const Comp = asChild ? Slot : "button"; 47 47 return ( 48 48 <Comp 49 49 className={cn(buttonVariants({ variant, size, className }))} 50 50 ref={ref} 51 + disabled={disabled} 51 52 {...props} 52 53 /> 53 54 );