feat: improve theme selector and UI components

- Updated `ThemeSelector` to use a new `ThemePreview` component for better theme visualization.
- Refactored button implementation in `ThemeSelector` to utilize the new `Button` component, enhancing consistency.
- Added a UI showcase section in `GeneralSettingsPageClient` to display available UI components with different themes.
- Enhanced `Badge`, `Button`, and `Input` components with new variants and improved styling for better usability and visual appeal.
- Updated CSS variables in `globals.css` for improved contrast and accessibility across themes.
This commit is contained in:
Julien Froidefond
2025-09-28 21:08:48 +02:00
parent 9ef23dbddc
commit 0e2eaf1052
12 changed files with 694 additions and 202 deletions

View File

@@ -1,38 +1,33 @@
import { HTMLAttributes, forwardRef } from 'react';
import { cn } from '@/lib/utils';
interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
variant?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'outline';
size?: 'sm' | 'md';
interface BadgeProps extends HTMLAttributes<HTMLDivElement> {
variant?: 'default' | 'primary' | 'success' | 'destructive' | 'accent' | 'purple' | 'yellow' | 'green' | 'blue' | 'gray';
}
const Badge = forwardRef<HTMLSpanElement, BadgeProps>(
({ className, variant = 'default', size = 'md', ...props }, ref) => {
const baseStyles = 'inline-flex items-center font-mono font-medium transition-all duration-200';
const Badge = forwardRef<HTMLDivElement, BadgeProps>(
({ className, variant = 'default', ...props }, ref) => {
const variants = {
default: 'bg-[var(--card)] text-[var(--muted-foreground)] border border-[var(--border)]',
primary: 'bg-[var(--primary)]/20 text-[var(--primary)] border border-[var(--primary)]/30',
success: 'bg-[var(--success)]/20 text-[var(--success)] border border-[var(--success)]/30',
warning: 'bg-[var(--accent)]/20 text-[var(--accent)] border border-[var(--accent)]/30',
danger: 'bg-[var(--destructive)]/20 text-[var(--destructive)] border border-[var(--destructive)]/30',
outline: 'bg-transparent text-[var(--muted-foreground)] border border-[var(--border)] hover:bg-[var(--card-hover)] hover:text-[var(--foreground)]'
default: 'bg-[var(--card)] text-[var(--foreground)] border border-[var(--border)]',
primary: 'bg-[color-mix(in_srgb,var(--primary)_10%,transparent)] text-[var(--primary)] border border-[color-mix(in_srgb,var(--primary)_25%,var(--border))]',
success: 'bg-[color-mix(in_srgb,var(--success)_10%,transparent)] text-[var(--success)] border border-[color-mix(in_srgb,var(--success)_25%,var(--border))]',
destructive: 'bg-[color-mix(in_srgb,var(--destructive)_10%,transparent)] text-[var(--destructive)] border border-[color-mix(in_srgb,var(--destructive)_25%,var(--border))]',
accent: 'bg-[color-mix(in_srgb,var(--accent)_10%,transparent)] text-[var(--accent)] border border-[color-mix(in_srgb,var(--accent)_25%,var(--border))]',
purple: 'bg-[color-mix(in_srgb,var(--purple)_10%,transparent)] text-[var(--purple)] border border-[color-mix(in_srgb,var(--purple)_25%,var(--border))]',
yellow: 'bg-[color-mix(in_srgb,var(--yellow)_10%,transparent)] text-[var(--yellow)] border border-[color-mix(in_srgb,var(--yellow)_25%,var(--border))]',
green: 'bg-[color-mix(in_srgb,var(--green)_10%,transparent)] text-[var(--green)] border border-[color-mix(in_srgb,var(--green)_25%,var(--border))]',
blue: 'bg-[color-mix(in_srgb,var(--blue)_10%,transparent)] text-[var(--blue)] border border-[color-mix(in_srgb,var(--blue)_25%,var(--border))]',
gray: 'bg-[color-mix(in_srgb,var(--gray)_10%,transparent)] text-[var(--gray)] border border-[color-mix(in_srgb,var(--gray)_25%,var(--border))]'
};
const sizes = {
sm: 'px-1.5 py-0.5 text-xs rounded',
md: 'px-2 py-1 text-xs rounded-md'
};
return (
<span
<div
ref={ref}
className={cn(
baseStyles,
'inline-flex items-center rounded-md px-2.5 py-0.5 text-xs font-medium transition-colors',
variants[variant],
sizes[size],
className
)}
ref={ref}
{...props}
/>
);
@@ -41,4 +36,4 @@ const Badge = forwardRef<HTMLSpanElement, BadgeProps>(
Badge.displayName = 'Badge';
export { Badge };
export { Badge };