chore: shadcn/ui component updates (batch)
This commit is contained in:
parent
6d60eebe1a
commit
3b555e4d8e
|
|
@ -1,7 +1,6 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
const Skeleton = React.forwardRef(({ className, variant = 'line', ...props }, ref) => {
|
function Skeleton({ className, variant = 'line', ref, ...props }) {
|
||||||
const variants = {
|
const variants = {
|
||||||
line: 'h-4 w-full rounded-md',
|
line: 'h-4 w-full rounded-md',
|
||||||
circle: 'h-10 w-10 rounded-full',
|
circle: 'h-10 w-10 rounded-full',
|
||||||
|
|
@ -21,7 +20,6 @@ const Skeleton = React.forwardRef(({ className, variant = 'line', ...props }, re
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
Skeleton.displayName = 'Skeleton';
|
|
||||||
|
|
||||||
export { Skeleton };
|
export { Skeleton };
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { cva } from 'class-variance-authority';
|
import { cva } from 'class-variance-authority';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { Slot } from '@radix-ui/react-slot';
|
import { Slot } from '@radix-ui/react-slot';
|
||||||
import { cva } from 'class-variance-authority';
|
import { cva } from 'class-variance-authority';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
@ -29,7 +28,7 @@ const buttonVariants = cva(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const Button = React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
|
function Button({ className, variant, size, asChild = false, ref, ...props }) {
|
||||||
const Comp = asChild ? Slot : 'button';
|
const Comp = asChild ? Slot : 'button';
|
||||||
return (
|
return (
|
||||||
<Comp
|
<Comp
|
||||||
|
|
@ -38,7 +37,6 @@ const Button = React.forwardRef(({ className, variant, size, asChild = false, ..
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
Button.displayName = 'Button';
|
|
||||||
|
|
||||||
export { Button, buttonVariants };
|
export { Button, buttonVariants };
|
||||||
|
|
|
||||||
|
|
@ -1,58 +1,63 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
const Card = React.forwardRef(({ className, ...props }, ref) => (
|
function Card({ className, ref, ...props }) {
|
||||||
<div
|
return (
|
||||||
ref={ref}
|
<div
|
||||||
className={cn('rounded-2xl border border-border/80 bg-card/95 text-card-foreground shadow-sm shadow-black/10 transition-shadow hover:shadow-md hover:shadow-black/10', className)}
|
ref={ref}
|
||||||
{...props}
|
className={cn('rounded-2xl border border-border/80 bg-card/95 text-card-foreground shadow-sm shadow-black/10 transition-shadow hover:shadow-md hover:shadow-black/10', className)}
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
Card.displayName = 'Card';
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const CardHeader = React.forwardRef(({ className, ...props }, ref) => (
|
function CardHeader({ className, ref, ...props }) {
|
||||||
<div
|
return (
|
||||||
ref={ref}
|
<div
|
||||||
className={cn('flex flex-col space-y-1.5 p-6', className)}
|
ref={ref}
|
||||||
{...props}
|
className={cn('flex flex-col space-y-1.5 p-6', className)}
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
CardHeader.displayName = 'CardHeader';
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const CardTitle = React.forwardRef(({ className, ...props }, ref) => (
|
function CardTitle({ className, ref, ...props }) {
|
||||||
<div
|
return (
|
||||||
ref={ref}
|
<div
|
||||||
className={cn('font-semibold leading-tight text-foreground', className)}
|
ref={ref}
|
||||||
{...props}
|
className={cn('font-semibold leading-tight text-foreground', className)}
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
CardTitle.displayName = 'CardTitle';
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const CardDescription = React.forwardRef(({ className, ...props }, ref) => (
|
function CardDescription({ className, ref, ...props }) {
|
||||||
<div
|
return (
|
||||||
ref={ref}
|
<div
|
||||||
className={cn('text-sm font-medium leading-relaxed text-muted-foreground', className)}
|
ref={ref}
|
||||||
{...props}
|
className={cn('text-sm font-medium leading-relaxed text-muted-foreground', className)}
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
CardDescription.displayName = 'CardDescription';
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const CardContent = React.forwardRef(({ className, ...props }, ref) => (
|
function CardContent({ className, ref, ...props }) {
|
||||||
<div
|
return (
|
||||||
ref={ref}
|
<div
|
||||||
className={cn('p-6 pt-0', className)}
|
ref={ref}
|
||||||
{...props}
|
className={cn('p-6 pt-0', className)}
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
CardContent.displayName = 'CardContent';
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const CardFooter = React.forwardRef(({ className, ...props }, ref) => (
|
function CardFooter({ className, ref, ...props }) {
|
||||||
<div
|
return (
|
||||||
ref={ref}
|
<div
|
||||||
className={cn('flex items-center p-6 pt-0', className)}
|
ref={ref}
|
||||||
{...props}
|
className={cn('flex items-center p-6 pt-0', className)}
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
CardFooter.displayName = 'CardFooter';
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter };
|
export { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter };
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,24 @@
|
||||||
import * as React from 'react';
|
|
||||||
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
||||||
import { Check } from 'lucide-react';
|
import { Check } from 'lucide-react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
const Checkbox = React.forwardRef(({ className, ...props }, ref) => (
|
function Checkbox({ className, ref, ...props }) {
|
||||||
<CheckboxPrimitive.Root
|
return (
|
||||||
ref={ref}
|
<CheckboxPrimitive.Root
|
||||||
className={cn(
|
ref={ref}
|
||||||
'peer h-4 w-4 shrink-0 rounded-sm border border-input bg-background shadow-sm transition-all focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',
|
className={cn(
|
||||||
className
|
'peer h-4 w-4 shrink-0 rounded-sm border border-input bg-background shadow-sm transition-all focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',
|
||||||
)}
|
className
|
||||||
{...props}
|
)}
|
||||||
>
|
{...props}
|
||||||
<CheckboxPrimitive.Indicator
|
|
||||||
className={cn('flex items-center justify-center text-current')}
|
|
||||||
>
|
>
|
||||||
<Check className="h-4 w-4" />
|
<CheckboxPrimitive.Indicator
|
||||||
</CheckboxPrimitive.Indicator>
|
className={cn('flex items-center justify-center text-current')}
|
||||||
</CheckboxPrimitive.Root>
|
>
|
||||||
));
|
<Check className="h-4 w-4" />
|
||||||
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
|
</CheckboxPrimitive.Indicator>
|
||||||
|
</CheckboxPrimitive.Root>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export { Checkbox };
|
export { Checkbox };
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
import * as React from 'react';
|
|
||||||
import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
|
import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
|
||||||
|
|
||||||
const Collapsible = CollapsiblePrimitive.Root;
|
const Collapsible = CollapsiblePrimitive.Root;
|
||||||
|
|
||||||
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
|
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
|
||||||
|
|
||||||
const CollapsibleContent = React.forwardRef(({ className, ...props }, ref) => (
|
function CollapsibleContent({ ref, ...props }) {
|
||||||
<CollapsiblePrimitive.Content
|
return (
|
||||||
ref={ref}
|
<CollapsiblePrimitive.Content
|
||||||
className="overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down"
|
ref={ref}
|
||||||
{...props}
|
className="overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down"
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
CollapsibleContent.displayName = CollapsiblePrimitive.Content.displayName;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
|
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import * as React from 'react';
|
|
||||||
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
||||||
import { X } from 'lucide-react';
|
import { X } from 'lucide-react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
@ -8,74 +7,80 @@ const DialogTrigger = DialogPrimitive.Trigger;
|
||||||
const DialogPortal = DialogPrimitive.Portal;
|
const DialogPortal = DialogPrimitive.Portal;
|
||||||
const DialogClose = DialogPrimitive.Close;
|
const DialogClose = DialogPrimitive.Close;
|
||||||
|
|
||||||
const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => (
|
function DialogOverlay({ className, ref, ...props }) {
|
||||||
<DialogPrimitive.Overlay
|
return (
|
||||||
ref={ref}
|
<DialogPrimitive.Overlay
|
||||||
className={cn(
|
|
||||||
'fixed inset-0 z-50 bg-foreground/25 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
||||||
|
|
||||||
const DialogContent = React.forwardRef(({ className, children, ...props }, ref) => (
|
|
||||||
<DialogPortal>
|
|
||||||
<DialogOverlay />
|
|
||||||
<DialogPrimitive.Content
|
|
||||||
ref={ref}
|
ref={ref}
|
||||||
role="dialog"
|
|
||||||
aria-modal="true"
|
|
||||||
className={cn(
|
className={cn(
|
||||||
'fixed left-[50%] top-[50%] z-50 grid w-[calc(100%-1rem)] max-w-lg max-h-[calc(100svh-1rem)] translate-x-[-50%] translate-y-[-50%] gap-4 overflow-y-auto rounded-2xl border border-border/70 bg-card p-4 text-card-foreground shadow-xl duration-200 sm:w-full sm:max-h-[calc(100svh-2rem)] sm:p-6 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]',
|
'fixed inset-0 z-50 bg-foreground/25 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
/>
|
||||||
{children}
|
);
|
||||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-full p-1 opacity-70 transition-all hover:bg-accent hover:opacity-100 focus:outline-none focus:ring-[3px] focus:ring-ring/50 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground" aria-label="Close dialog">
|
}
|
||||||
<X className="h-4 w-4" />
|
|
||||||
<span className="sr-only">Close</span>
|
|
||||||
</DialogPrimitive.Close>
|
|
||||||
</DialogPrimitive.Content>
|
|
||||||
</DialogPortal>
|
|
||||||
));
|
|
||||||
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
||||||
|
|
||||||
const DialogHeader = ({ className, ...props }) => (
|
function DialogContent({ className, children, ref, ...props }) {
|
||||||
<div
|
return (
|
||||||
className={cn('flex flex-col space-y-1.5 text-center sm:text-left', className)}
|
<DialogPortal>
|
||||||
{...props}
|
<DialogOverlay />
|
||||||
/>
|
<DialogPrimitive.Content
|
||||||
);
|
ref={ref}
|
||||||
DialogHeader.displayName = 'DialogHeader';
|
role="dialog"
|
||||||
|
aria-modal="true"
|
||||||
|
className={cn(
|
||||||
|
'fixed left-[50%] top-[50%] z-50 grid w-[calc(100%-1rem)] max-w-lg max-h-[calc(100svh-1rem)] translate-x-[-50%] translate-y-[-50%] gap-4 overflow-y-auto rounded-2xl border border-border/70 bg-card p-4 text-card-foreground shadow-xl duration-200 sm:w-full sm:max-h-[calc(100svh-2rem)] sm:p-6 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]',
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-full p-1 opacity-70 transition-all hover:bg-accent hover:opacity-100 focus:outline-none focus:ring-[3px] focus:ring-ring/50 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground" aria-label="Close dialog">
|
||||||
|
<X className="h-4 w-4" />
|
||||||
|
<span className="sr-only">Close</span>
|
||||||
|
</DialogPrimitive.Close>
|
||||||
|
</DialogPrimitive.Content>
|
||||||
|
</DialogPortal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const DialogFooter = ({ className, ...props }) => (
|
function DialogHeader({ className, ...props }) {
|
||||||
<div
|
return (
|
||||||
className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)}
|
<div
|
||||||
{...props}
|
className={cn('flex flex-col space-y-1.5 text-center sm:text-left', className)}
|
||||||
/>
|
{...props}
|
||||||
);
|
/>
|
||||||
DialogFooter.displayName = 'DialogFooter';
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const DialogTitle = React.forwardRef(({ className, ...props }, ref) => (
|
function DialogFooter({ className, ...props }) {
|
||||||
<DialogPrimitive.Title
|
return (
|
||||||
ref={ref}
|
<div
|
||||||
className={cn('text-lg font-semibold leading-none tracking-tight', className)}
|
className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
));
|
);
|
||||||
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
}
|
||||||
|
|
||||||
const DialogDescription = React.forwardRef(({ className, ...props }, ref) => (
|
function DialogTitle({ className, ref, ...props }) {
|
||||||
<DialogPrimitive.Description
|
return (
|
||||||
ref={ref}
|
<DialogPrimitive.Title
|
||||||
className={cn('text-sm text-muted-foreground', className)}
|
ref={ref}
|
||||||
{...props}
|
className={cn('text-lg font-semibold leading-none tracking-tight', className)}
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function DialogDescription({ className, ref, ...props }) {
|
||||||
|
return (
|
||||||
|
<DialogPrimitive.Description
|
||||||
|
ref={ref}
|
||||||
|
className={cn('text-sm text-muted-foreground', className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Dialog,
|
Dialog,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
const Input = React.forwardRef(({ className, type, ...props }, ref) => {
|
function Input({ className, type, ref, ...props }) {
|
||||||
return (
|
return (
|
||||||
<input
|
<input
|
||||||
type={type}
|
type={type}
|
||||||
|
|
@ -13,7 +12,6 @@ const Input = React.forwardRef(({ className, type, ...props }, ref) => {
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
Input.displayName = 'Input';
|
|
||||||
|
|
||||||
export { Input };
|
export { Input };
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import * as React from 'react';
|
|
||||||
import * as LabelPrimitive from '@radix-ui/react-label';
|
import * as LabelPrimitive from '@radix-ui/react-label';
|
||||||
import { cva } from 'class-variance-authority';
|
import { cva } from 'class-variance-authority';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
@ -7,13 +6,14 @@ const labelVariants = cva(
|
||||||
'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70'
|
'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70'
|
||||||
);
|
);
|
||||||
|
|
||||||
const Label = React.forwardRef(({ className, ...props }, ref) => (
|
function Label({ className, ref, ...props }) {
|
||||||
<LabelPrimitive.Root
|
return (
|
||||||
ref={ref}
|
<LabelPrimitive.Root
|
||||||
className={cn(labelVariants(), className)}
|
ref={ref}
|
||||||
{...props}
|
className={cn(labelVariants(), className)}
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
Label.displayName = LabelPrimitive.Root.displayName;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export { Label };
|
export { Label };
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import * as React from 'react';
|
|
||||||
import * as SelectPrimitive from '@radix-ui/react-select';
|
import * as SelectPrimitive from '@radix-ui/react-select';
|
||||||
import { Check, ChevronDown, ChevronUp } from 'lucide-react';
|
import { Check, ChevronDown, ChevronUp } from 'lucide-react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
@ -7,116 +6,123 @@ const Select = SelectPrimitive.Root;
|
||||||
const SelectGroup = SelectPrimitive.Group;
|
const SelectGroup = SelectPrimitive.Group;
|
||||||
const SelectValue = SelectPrimitive.Value;
|
const SelectValue = SelectPrimitive.Value;
|
||||||
|
|
||||||
const SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => (
|
function SelectTrigger({ className, children, ref, ...props }) {
|
||||||
<SelectPrimitive.Trigger
|
return (
|
||||||
ref={ref}
|
<SelectPrimitive.Trigger
|
||||||
className={cn(
|
|
||||||
'flex h-9 w-full items-center justify-between whitespace-nowrap rounded-lg border border-input bg-card/70 px-3 py-2 text-sm font-medium text-foreground shadow-sm shadow-black/5 transition-all placeholder:text-muted-foreground/80 focus:outline-none focus:ring-[3px] focus:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
aria-haspopup="listbox"
|
|
||||||
aria-expanded={false}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
<SelectPrimitive.Icon asChild>
|
|
||||||
<ChevronDown className="h-4 w-4 text-muted-foreground" />
|
|
||||||
</SelectPrimitive.Icon>
|
|
||||||
</SelectPrimitive.Trigger>
|
|
||||||
));
|
|
||||||
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
||||||
|
|
||||||
const SelectScrollUpButton = React.forwardRef(({ className, ...props }, ref) => (
|
|
||||||
<SelectPrimitive.ScrollUpButton
|
|
||||||
ref={ref}
|
|
||||||
className={cn('flex cursor-default items-center justify-center py-1', className)}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
<ChevronUp className="h-4 w-4" />
|
|
||||||
</SelectPrimitive.ScrollUpButton>
|
|
||||||
));
|
|
||||||
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
||||||
|
|
||||||
const SelectScrollDownButton = React.forwardRef(({ className, ...props }, ref) => (
|
|
||||||
<SelectPrimitive.ScrollDownButton
|
|
||||||
ref={ref}
|
|
||||||
className={cn('flex cursor-default items-center justify-center py-1', className)}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
<ChevronDown className="h-4 w-4" />
|
|
||||||
</SelectPrimitive.ScrollDownButton>
|
|
||||||
));
|
|
||||||
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
||||||
|
|
||||||
const SelectContent = React.forwardRef(({ className, children, position = 'popper', ...props }, ref) => (
|
|
||||||
<SelectPrimitive.Portal>
|
|
||||||
<SelectPrimitive.Content
|
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-xl border border-border/80 bg-popover/95 text-popover-foreground shadow-xl shadow-black/25 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
|
'flex h-9 w-full items-center justify-between whitespace-nowrap rounded-lg border border-input bg-card/70 px-3 py-2 text-sm font-medium text-foreground shadow-sm shadow-black/5 transition-all placeholder:text-muted-foreground/80 focus:outline-none focus:ring-[3px] focus:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
|
||||||
position === 'popper' &&
|
|
||||||
'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
|
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
role="listbox"
|
aria-haspopup="listbox"
|
||||||
aria-orientation="vertical"
|
aria-expanded={false}
|
||||||
position={position}
|
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<SelectScrollUpButton />
|
{children}
|
||||||
<SelectPrimitive.Viewport
|
<SelectPrimitive.Icon asChild>
|
||||||
|
<ChevronDown className="h-4 w-4 text-muted-foreground" />
|
||||||
|
</SelectPrimitive.Icon>
|
||||||
|
</SelectPrimitive.Trigger>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectScrollUpButton({ className, ref, ...props }) {
|
||||||
|
return (
|
||||||
|
<SelectPrimitive.ScrollUpButton
|
||||||
|
ref={ref}
|
||||||
|
className={cn('flex cursor-default items-center justify-center py-1', className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ChevronUp className="h-4 w-4" />
|
||||||
|
</SelectPrimitive.ScrollUpButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectScrollDownButton({ className, ref, ...props }) {
|
||||||
|
return (
|
||||||
|
<SelectPrimitive.ScrollDownButton
|
||||||
|
ref={ref}
|
||||||
|
className={cn('flex cursor-default items-center justify-center py-1', className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ChevronDown className="h-4 w-4" />
|
||||||
|
</SelectPrimitive.ScrollDownButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectContent({ className, children, position = 'popper', ref, ...props }) {
|
||||||
|
return (
|
||||||
|
<SelectPrimitive.Portal>
|
||||||
|
<SelectPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
'p-1',
|
'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-xl border border-border/80 bg-popover/95 text-popover-foreground shadow-xl shadow-black/25 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
|
||||||
position === 'popper' &&
|
position === 'popper' &&
|
||||||
'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]'
|
'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
|
||||||
|
className
|
||||||
)}
|
)}
|
||||||
|
role="listbox"
|
||||||
|
aria-orientation="vertical"
|
||||||
|
position={position}
|
||||||
|
{...props}
|
||||||
>
|
>
|
||||||
{children}
|
<SelectScrollUpButton />
|
||||||
</SelectPrimitive.Viewport>
|
<SelectPrimitive.Viewport
|
||||||
<SelectScrollDownButton />
|
className={cn(
|
||||||
</SelectPrimitive.Content>
|
'p-1',
|
||||||
</SelectPrimitive.Portal>
|
position === 'popper' &&
|
||||||
));
|
'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]'
|
||||||
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
)}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</SelectPrimitive.Viewport>
|
||||||
|
<SelectScrollDownButton />
|
||||||
|
</SelectPrimitive.Content>
|
||||||
|
</SelectPrimitive.Portal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const SelectLabel = React.forwardRef(({ className, ...props }, ref) => (
|
function SelectLabel({ className, ref, ...props }) {
|
||||||
<SelectPrimitive.Label
|
return (
|
||||||
ref={ref}
|
<SelectPrimitive.Label
|
||||||
className={cn('px-2 py-1.5 text-sm font-semibold', className)}
|
ref={ref}
|
||||||
{...props}
|
className={cn('px-2 py-1.5 text-sm font-semibold', className)}
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const SelectItem = React.forwardRef(({ className, children, ...props }, ref) => (
|
function SelectItem({ className, children, ref, ...props }) {
|
||||||
<SelectPrimitive.Item
|
return (
|
||||||
ref={ref}
|
<SelectPrimitive.Item
|
||||||
className={cn(
|
ref={ref}
|
||||||
'relative flex w-full cursor-pointer select-none items-center rounded-lg py-1.5 pl-2 pr-8 text-sm font-medium outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',
|
className={cn(
|
||||||
className
|
'relative flex w-full cursor-pointer select-none items-center rounded-lg py-1.5 pl-2 pr-8 text-sm font-medium outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',
|
||||||
)}
|
className
|
||||||
role="option"
|
)}
|
||||||
{...props}
|
role="option"
|
||||||
>
|
{...props}
|
||||||
<span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
|
>
|
||||||
<SelectPrimitive.ItemIndicator>
|
<span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||||
<Check className="h-4 w-4" />
|
<SelectPrimitive.ItemIndicator>
|
||||||
</SelectPrimitive.ItemIndicator>
|
<Check className="h-4 w-4" />
|
||||||
</span>
|
</SelectPrimitive.ItemIndicator>
|
||||||
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
</span>
|
||||||
</SelectPrimitive.Item>
|
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
||||||
));
|
</SelectPrimitive.Item>
|
||||||
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const SelectSeparator = React.forwardRef(({ className, ...props }, ref) => (
|
function SelectSeparator({ className, ref, ...props }) {
|
||||||
<SelectPrimitive.Separator
|
return (
|
||||||
ref={ref}
|
<SelectPrimitive.Separator
|
||||||
className={cn('-mx-1 my-1 h-px bg-muted', className)}
|
ref={ref}
|
||||||
role="separator"
|
className={cn('-mx-1 my-1 h-px bg-muted', className)}
|
||||||
{...props}
|
role="separator"
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Select,
|
Select,
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import * as React from 'react';
|
|
||||||
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
const Separator = React.forwardRef(
|
function Separator({ className, orientation = 'horizontal', decorative = true, ref, ...props }) {
|
||||||
({ className, orientation = 'horizontal', decorative = true, ...props }, ref) => (
|
return (
|
||||||
<SeparatorPrimitive.Root
|
<SeparatorPrimitive.Root
|
||||||
ref={ref}
|
ref={ref}
|
||||||
decorative={decorative}
|
decorative={decorative}
|
||||||
|
|
@ -15,8 +14,7 @@ const Separator = React.forwardRef(
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
)
|
);
|
||||||
);
|
}
|
||||||
Separator.displayName = SeparatorPrimitive.Root.displayName;
|
|
||||||
|
|
||||||
export { Separator };
|
export { Separator };
|
||||||
|
|
|
||||||
|
|
@ -1,116 +1,122 @@
|
||||||
|
|
||||||
import * as React from 'react';
|
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
const Table = React.forwardRef(({ className, ...props }, ref) => (
|
function Table({ className, ref, ...props }) {
|
||||||
<div className="relative w-full overflow-auto">
|
return (
|
||||||
<table
|
<div className="relative w-full overflow-auto">
|
||||||
|
<table
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'w-full caption-bottom text-sm',
|
||||||
|
'border-collapse',
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function TableHeader({ className, ref, ...props }) {
|
||||||
|
return (
|
||||||
|
<thead
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
'w-full caption-bottom text-sm',
|
'[&_tr]:border-b [&_tr]:border-border/60',
|
||||||
'border-collapse',
|
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
</div>
|
);
|
||||||
));
|
}
|
||||||
Table.displayName = 'Table';
|
|
||||||
|
|
||||||
const TableHeader = React.forwardRef(({ className, ...props }, ref) => (
|
function TableBody({ className, ref, ...props }) {
|
||||||
<thead
|
return (
|
||||||
ref={ref}
|
<tbody
|
||||||
className={cn(
|
ref={ref}
|
||||||
'[&_tr]:border-b [&_tr]:border-border/60',
|
className={cn(
|
||||||
className
|
'[&_tr:last-child]:border-0',
|
||||||
)}
|
className
|
||||||
{...props}
|
)}
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
TableHeader.displayName = 'TableHeader';
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const TableBody = React.forwardRef(({ className, ...props }, ref) => (
|
function TableFooter({ className, ref, ...props }) {
|
||||||
<tbody
|
return (
|
||||||
ref={ref}
|
<tfoot
|
||||||
className={cn(
|
ref={ref}
|
||||||
'[&_tr:last-child]:border-0',
|
className={cn(
|
||||||
className
|
'border-t border-border/60 bg-muted/50 font-medium',
|
||||||
)}
|
'[&>tr]:last:border-b-0',
|
||||||
{...props}
|
className
|
||||||
/>
|
)}
|
||||||
));
|
{...props}
|
||||||
TableBody.displayName = 'TableBody';
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const TableFooter = React.forwardRef(({ className, ...props }, ref) => (
|
function TableRow({ className, ref, ...props }) {
|
||||||
<tfoot
|
return (
|
||||||
ref={ref}
|
<tr
|
||||||
className={cn(
|
ref={ref}
|
||||||
'border-t border-border/60 bg-muted/50 font-medium',
|
className={cn(
|
||||||
'[&>tr]:last:border-b-0',
|
'border-b border-border/50 last:border-0',
|
||||||
className
|
'transition-colors duration-150',
|
||||||
)}
|
'hover:bg-accent/50',
|
||||||
{...props}
|
'data-[state=selected]:bg-accent/70',
|
||||||
/>
|
className
|
||||||
));
|
)}
|
||||||
TableFooter.displayName = 'TableFooter';
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const TableRow = React.forwardRef(({ className, ...props }, ref) => (
|
function TableHead({ className, ref, ...props }) {
|
||||||
<tr
|
return (
|
||||||
ref={ref}
|
<th
|
||||||
className={cn(
|
ref={ref}
|
||||||
'border-b border-border/50 last:border-0',
|
className={cn(
|
||||||
'transition-colors duration-150',
|
'h-10 px-4 text-left align-middle',
|
||||||
'hover:bg-accent/50',
|
'text-xs font-semibold uppercase tracking-normal',
|
||||||
'data-[state=selected]:bg-accent/70',
|
'text-muted-foreground',
|
||||||
className
|
'[&:has([role=checkbox])]:pr-0',
|
||||||
)}
|
'[&>[role=checkbox]]:translate-y-[2px]',
|
||||||
{...props}
|
className
|
||||||
/>
|
)}
|
||||||
));
|
{...props}
|
||||||
TableRow.displayName = 'TableRow';
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const TableHead = React.forwardRef(({ className, ...props }, ref) => (
|
function TableCell({ className, ref, ...props }) {
|
||||||
<th
|
return (
|
||||||
ref={ref}
|
<td
|
||||||
className={cn(
|
ref={ref}
|
||||||
'h-10 px-4 text-left align-middle',
|
className={cn(
|
||||||
'text-xs font-semibold uppercase tracking-normal',
|
'px-5 py-3 align-middle',
|
||||||
'text-muted-foreground',
|
'text-sm font-medium text-foreground',
|
||||||
'[&:has([role=checkbox])]:pr-0',
|
'[&:has([role=checkbox])]:pr-0',
|
||||||
'[&>[role=checkbox]]:translate-y-[2px]',
|
'[&>[role=checkbox]]:translate-y-[2px]',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
));
|
);
|
||||||
TableHead.displayName = 'TableHead';
|
}
|
||||||
|
|
||||||
const TableCell = React.forwardRef(({ className, ...props }, ref) => (
|
function TableCaption({ className, ref, ...props }) {
|
||||||
<td
|
return (
|
||||||
ref={ref}
|
<caption
|
||||||
className={cn(
|
ref={ref}
|
||||||
'px-5 py-3 align-middle',
|
className={cn(
|
||||||
'text-sm font-medium text-foreground',
|
'mt-4 text-sm text-muted-foreground',
|
||||||
'[&:has([role=checkbox])]:pr-0',
|
className
|
||||||
'[&>[role=checkbox]]:translate-y-[2px]',
|
)}
|
||||||
className
|
{...props}
|
||||||
)}
|
/>
|
||||||
{...props}
|
);
|
||||||
/>
|
}
|
||||||
));
|
|
||||||
TableCell.displayName = 'TableCell';
|
|
||||||
|
|
||||||
const TableCaption = React.forwardRef(({ className, ...props }, ref) => (
|
|
||||||
<caption
|
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
'mt-4 text-sm text-muted-foreground',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
TableCaption.displayName = 'TableCaption';
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Table,
|
Table,
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,45 @@
|
||||||
import * as React from 'react';
|
|
||||||
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
const Tabs = TabsPrimitive.Root;
|
const Tabs = TabsPrimitive.Root;
|
||||||
|
|
||||||
const TabsList = React.forwardRef(({ className, ...props }, ref) => (
|
function TabsList({ className, ref, ...props }) {
|
||||||
<TabsPrimitive.List
|
return (
|
||||||
ref={ref}
|
<TabsPrimitive.List
|
||||||
className={cn(
|
ref={ref}
|
||||||
'inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground',
|
className={cn(
|
||||||
className
|
'inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground',
|
||||||
)}
|
className
|
||||||
{...props}
|
)}
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
TabsList.displayName = TabsPrimitive.List.displayName;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => (
|
function TabsTrigger({ className, ref, ...props }) {
|
||||||
<TabsPrimitive.Trigger
|
return (
|
||||||
ref={ref}
|
<TabsPrimitive.Trigger
|
||||||
className={cn(
|
ref={ref}
|
||||||
'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',
|
className={cn(
|
||||||
className
|
'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',
|
||||||
)}
|
className
|
||||||
{...props}
|
)}
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const TabsContent = React.forwardRef(({ className, ...props }, ref) => (
|
function TabsContent({ className, ref, ...props }) {
|
||||||
<TabsPrimitive.Content
|
return (
|
||||||
ref={ref}
|
<TabsPrimitive.Content
|
||||||
className={cn(
|
ref={ref}
|
||||||
'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
className={cn(
|
||||||
className
|
'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
||||||
)}
|
className
|
||||||
{...props}
|
)}
|
||||||
/>
|
{...props}
|
||||||
));
|
/>
|
||||||
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export { Tabs, TabsList, TabsTrigger, TabsContent };
|
export { Tabs, TabsList, TabsTrigger, TabsContent };
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import * as React from 'react';
|
|
||||||
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
||||||
import { Sun, Moon } from 'lucide-react';
|
import { Sun, Moon } from 'lucide-react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
@ -9,39 +8,41 @@ import { useTheme } from '@/contexts/ThemeContext';
|
||||||
const DropdownMenu = DropdownMenuPrimitive.Root;
|
const DropdownMenu = DropdownMenuPrimitive.Root;
|
||||||
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
||||||
|
|
||||||
const DropdownMenuContent = React.forwardRef(({ className, sideOffset = 6, ...props }, ref) => (
|
function DropdownMenuContent({ className, sideOffset = 6, ref, ...props }) {
|
||||||
<DropdownMenuPrimitive.Portal>
|
return (
|
||||||
<DropdownMenuPrimitive.Content
|
<DropdownMenuPrimitive.Portal>
|
||||||
|
<DropdownMenuPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
sideOffset={sideOffset}
|
||||||
|
className={cn(
|
||||||
|
'z-50 min-w-[140px] overflow-hidden rounded-xl border border-border/70 bg-popover/95 p-1 text-popover-foreground shadow-xl backdrop-blur-sm',
|
||||||
|
'data-[state=open]:animate-in data-[state=closed]:animate-out',
|
||||||
|
'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
||||||
|
'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
|
||||||
|
'data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2',
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</DropdownMenuPrimitive.Portal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function DropdownMenuItem({ className, inset, ref, ...props }) {
|
||||||
|
return (
|
||||||
|
<DropdownMenuPrimitive.Item
|
||||||
ref={ref}
|
ref={ref}
|
||||||
sideOffset={sideOffset}
|
|
||||||
className={cn(
|
className={cn(
|
||||||
'z-50 min-w-[140px] overflow-hidden rounded-xl border border-border/70 bg-popover/95 p-1 text-popover-foreground shadow-xl backdrop-blur-sm',
|
'relative flex cursor-pointer select-none items-center gap-2 rounded-lg px-2.5 py-2 text-sm outline-none',
|
||||||
'data-[state=open]:animate-in data-[state=closed]:animate-out',
|
'transition-colors focus:bg-accent focus:text-accent-foreground',
|
||||||
'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||||
'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
|
inset && 'pl-8',
|
||||||
'data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2',
|
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
</DropdownMenuPrimitive.Portal>
|
);
|
||||||
));
|
}
|
||||||
DropdownMenuContent.displayName = 'DropdownMenuContent';
|
|
||||||
|
|
||||||
const DropdownMenuItem = React.forwardRef(({ className, inset, ...props }, ref) => (
|
|
||||||
<DropdownMenuPrimitive.Item
|
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
|
||||||
'relative flex cursor-pointer select-none items-center gap-2 rounded-lg px-2.5 py-2 text-sm outline-none',
|
|
||||||
'transition-colors focus:bg-accent focus:text-accent-foreground',
|
|
||||||
'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
|
||||||
inset && 'pl-8',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
DropdownMenuItem.displayName = 'DropdownMenuItem';
|
|
||||||
|
|
||||||
/* ── Theme options config ───────────────────────────────────── */
|
/* ── Theme options config ───────────────────────────────────── */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import * as React from 'react';
|
|
||||||
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
|
@ -6,19 +5,20 @@ const TooltipProvider = TooltipPrimitive.Provider;
|
||||||
const Tooltip = TooltipPrimitive.Root;
|
const Tooltip = TooltipPrimitive.Root;
|
||||||
const TooltipTrigger = TooltipPrimitive.Trigger;
|
const TooltipTrigger = TooltipPrimitive.Trigger;
|
||||||
|
|
||||||
const TooltipContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => (
|
function TooltipContent({ className, sideOffset = 4, ref, ...props }) {
|
||||||
<TooltipPrimitive.Portal>
|
return (
|
||||||
<TooltipPrimitive.Content
|
<TooltipPrimitive.Portal>
|
||||||
ref={ref}
|
<TooltipPrimitive.Content
|
||||||
sideOffset={sideOffset}
|
ref={ref}
|
||||||
className={cn(
|
sideOffset={sideOffset}
|
||||||
'z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out 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',
|
className={cn(
|
||||||
className
|
'z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out 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',
|
||||||
)}
|
className
|
||||||
{...props}
|
)}
|
||||||
/>
|
{...props}
|
||||||
</TooltipPrimitive.Portal>
|
/>
|
||||||
));
|
</TooltipPrimitive.Portal>
|
||||||
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue