From 452aa392bdee0dbeab955a8a4d0f93cae5162796 Mon Sep 17 00:00:00 2001 From: Z8MB1E Date: Mon, 17 Aug 2026 22:18:31 -0400 Subject: [PATCH] feat(ui): enhance shadcn dialog, tabs, tooltip, and command components - Add showCloseButton prop to DialogContent for modal workflows - Add line variant to TabsList via class-variance-authority - Add arrowClassName prop to TooltipContent for arrow styling - Add optional title prop to CommandDialog for accessibility --- src/components/ui/command.tsx | 9 +++++++-- src/components/ui/dialog.tsx | 16 ++++++++++------ src/components/ui/tabs.tsx | 30 ++++++++++++++++++++++++------ src/components/ui/tooltip.tsx | 11 ++++++++--- 4 files changed, 49 insertions(+), 17 deletions(-) diff --git a/src/components/ui/command.tsx b/src/components/ui/command.tsx index dc859d7..1a59a6e 100644 --- a/src/components/ui/command.tsx +++ b/src/components/ui/command.tsx @@ -6,7 +6,7 @@ import { Command as CommandPrimitive } from "cmdk"; import { Search } from "lucide-react"; import { cn } from "@/lib/utils"; -import { Dialog, DialogContent } from "@/components/ui/dialog"; +import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog"; const Command = React.forwardRef< React.ElementRef, @@ -23,10 +23,15 @@ const Command = React.forwardRef< )); Command.displayName = CommandPrimitive.displayName; -const CommandDialog = ({ children, ...props }: DialogProps) => { +const CommandDialog = ({ + children, + title, + ...props +}: DialogProps & { title?: React.ReactNode }) => { return ( + {title && {title}} {children} diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index 9f10bfb..5aeed1a 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -31,8 +31,10 @@ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; const DialogContent = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( + React.ComponentPropsWithoutRef & { + showCloseButton?: boolean; + } +>(({ className, children, showCloseButton = true, ...props }, ref) => ( {children} - - - Close - + {showCloseButton && ( + + + Close + + )} )); diff --git a/src/components/ui/tabs.tsx b/src/components/ui/tabs.tsx index cc56f16..21375c2 100644 --- a/src/components/ui/tabs.tsx +++ b/src/components/ui/tabs.tsx @@ -2,21 +2,36 @@ import * as React from "react"; import * as TabsPrimitive from "@radix-ui/react-tabs"; +import { cva, type VariantProps } from "class-variance-authority"; import { cn } from "@/lib/utils"; const Tabs = TabsPrimitive.Root; +const tabsListVariants = cva( + "inline-flex items-center justify-center text-muted-foreground", + { + variants: { + variant: { + default: "h-9 rounded-lg bg-muted p-1", + line: "h-9 w-full justify-start gap-1 border-b border-border bg-transparent p-0 group", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +); + const TabsList = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, variant, ...props }, ref) => ( )); @@ -30,6 +45,9 @@ const TabsTrigger = React.forwardRef< ref={ref} className={cn( "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow", + // "line" variant: underline-style triggers (applies only when the parent + // TabsList has data-variant="line" + the `group` class from the cva above). + "group-data-[variant=line]:rounded-none group-data-[variant=line]:border-b-2 group-data-[variant=line]:border-transparent group-data-[variant=line]:bg-transparent group-data-[variant=line]:px-4 group-data-[variant=line]:py-2 group-data-[variant=line]:shadow-none group-data-[variant=line]:data-[state=active]:border-primary group-data-[variant=line]:data-[state=active]:bg-transparent group-data-[variant=line]:data-[state=active]:text-foreground group-data-[variant=line]:data-[state=active]:shadow-none", className, )} {...props} diff --git a/src/components/ui/tooltip.tsx b/src/components/ui/tooltip.tsx index b0834dd..42a34cf 100644 --- a/src/components/ui/tooltip.tsx +++ b/src/components/ui/tooltip.tsx @@ -13,8 +13,10 @@ const TooltipTrigger = TooltipPrimitive.Trigger; const TooltipContent = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, sideOffset = 4, ...props }, ref) => ( + React.ComponentPropsWithoutRef & { + arrowClassName?: string; + } +>(({ className, sideOffset = 4, arrowClassName, children, ...props }, ref) => ( + > + {arrowClassName && } + {children} + )); TooltipContent.displayName = TooltipPrimitive.Content.displayName;