learning_ai_common_plat/dashboards/admin-web/src/components/ui/button.tsx
root b6e996714d refactor(admin-web): integrate design tokens and improve accessibility
- Updated Badge component to use design token CSS variables (bl-*)
- Updated Button component to use design token CSS variables (bl-*)
- Improved focus states with proper design token colors
- Added aria-label to logout button in sidebar for better accessibility
- Maintains backward compatibility while improving consistency

This moves admin web toward design system compliance while ensuring
no breaking changes to existing functionality.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-11 02:06:04 +00:00

66 lines
2.6 KiB
TypeScript

import * as React from 'react';
import { cva, type VariantProps } from 'class-variance-authority';
import { Slot } from 'radix-ui';
import { cn } from '@/lib/utils';
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:ring-2 focus-visible:ring-[var(--bl-focus-ring)] focus-visible:ring-offset-2 aria-invalid:ring-[var(--bl-danger)] aria-invalid:border-[var(--bl-danger)]",
{
variants: {
variant: {
default:
'bg-[var(--bl-accent)] text-[var(--bl-accent-foreground)] hover:bg-[var(--bl-accent)]/90',
destructive:
'bg-[var(--bl-danger)] text-[var(--bl-danger-foreground)] hover:bg-[var(--bl-danger)]/90 focus-visible:ring-[var(--bl-danger)]/20 dark:focus-visible:ring-[var(--bl-danger)]/40 dark:bg-[var(--bl-danger)]/60',
outline:
'border bg-[var(--bl-surface-card)] shadow-xs hover:bg-[var(--bl-surface-muted)] hover:text-[var(--bl-text-primary)] dark:bg-[var(--bl-input)]/30 dark:border-[var(--bl-border)] dark:hover:bg-[var(--bl-input)]/50',
secondary:
'bg-[var(--bl-surface-muted)] text-[var(--bl-text-primary)] hover:bg-[var(--bl-surface-muted)]/80',
ghost:
'hover:bg-[var(--bl-surface-muted)] hover:text-[var(--bl-text-primary)] dark:hover:bg-[var(--bl-accent-muted)]/50',
link: 'text-[var(--bl-accent)] underline-offset-4 hover:underline',
},
size: {
default: 'h-9 px-4 py-2 has-[>svg]:px-3',
xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',
lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
icon: 'size-9',
'icon-xs': "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
'icon-sm': 'size-8',
'icon-lg': 'size-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
);
function Button({
className,
variant = 'default',
size = 'default',
asChild = false,
...props
}: React.ComponentProps<'button'> &
VariantProps<typeof buttonVariants> & {
asChild?: boolean;
}) {
const Comp = asChild ? Slot.Root : 'button';
return (
<Comp
data-slot="button"
data-variant={variant}
data-size={size}
className={cn(buttonVariants({ variant, size, className }))}
{...props}
/>
);
}
export { Button, buttonVariants };