Swap the main site dashboard chart from a bar chart to a line chart using 21st.dev's line-charts-6 component with dot grid background, glow shadow, and animated active dots. Add Badge trend indicators on metric cards using Phosphor icons. All existing features preserved (annotations, comparison, export, live indicator, interval controls). New UI primitives: line-charts-6, badge-2, card, button-1, avatar. Added shadcn-compatible CSS variables and Tailwind color mappings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
68 lines
2.1 KiB
TypeScript
68 lines
2.1 KiB
TypeScript
'use client';
|
|
|
|
import * as React from 'react';
|
|
import { cn } from '@/lib/utils';
|
|
import { cva, VariantProps } from 'class-variance-authority';
|
|
import { Avatar as AvatarPrimitive } from 'radix-ui';
|
|
|
|
const avatarStatusVariants = cva('flex items-center rounded-full size-2 border-2 border-background', {
|
|
variants: {
|
|
variant: {
|
|
online: 'bg-green-600',
|
|
offline: 'bg-zinc-600 dark:bg-zinc-300',
|
|
busy: 'bg-yellow-600',
|
|
away: 'bg-blue-600',
|
|
},
|
|
},
|
|
defaultVariants: {
|
|
variant: 'online',
|
|
},
|
|
});
|
|
|
|
function Avatar({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Root>) {
|
|
return (
|
|
<AvatarPrimitive.Root data-slot="avatar" className={cn('relative flex shrink-0 size-10', className)} {...props} />
|
|
);
|
|
}
|
|
|
|
function AvatarImage({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
|
|
return (
|
|
<div className={cn('relative overflow-hidden rounded-full', className)}>
|
|
<AvatarPrimitive.Image data-slot="avatar-image" className={cn('aspect-square h-full w-full')} {...props} />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function AvatarFallback({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
|
|
return (
|
|
<AvatarPrimitive.Fallback
|
|
data-slot="avatar-fallback"
|
|
className={cn(
|
|
'flex h-full w-full items-center justify-center rounded-full border border-border bg-accent text-accent-foreground text-xs',
|
|
className,
|
|
)}
|
|
{...props}
|
|
/>
|
|
);
|
|
}
|
|
|
|
function AvatarIndicator({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
return (
|
|
<div
|
|
data-slot="avatar-indicator"
|
|
className={cn('absolute flex size-6 items-center justify-center', className)}
|
|
{...props}
|
|
/>
|
|
);
|
|
}
|
|
|
|
function AvatarStatus({
|
|
className,
|
|
variant,
|
|
...props
|
|
}: React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof avatarStatusVariants>) {
|
|
return <div data-slot="avatar-status" className={cn(avatarStatusVariants({ variant }), className)} {...props} />;
|
|
}
|
|
|
|
export { Avatar, AvatarFallback, AvatarImage, AvatarIndicator, AvatarStatus, avatarStatusVariants };
|