feat(dashboard): integrate Checkbox component for comparison toggle in Chart, enhancing user interaction
This commit is contained in:
@@ -16,6 +16,7 @@ import type { TooltipProps } from 'recharts'
|
||||
import { formatNumber, formatDuration } from '@/lib/utils/format'
|
||||
import { ArrowTopRightIcon, ArrowBottomRightIcon, DownloadIcon, BarChartIcon } from '@radix-ui/react-icons'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import { Checkbox } from '@/components/ui/Checkbox'
|
||||
|
||||
const COLORS = {
|
||||
brand: '#FD5E0F',
|
||||
@@ -346,15 +347,11 @@ export default function Chart({ data, prevData, stats, prevStats, interval }: Ch
|
||||
{/* Right side: Controls */}
|
||||
<div className="flex items-center gap-3 self-end sm:self-auto">
|
||||
{prevData?.length ? (
|
||||
<label className="flex cursor-pointer items-center gap-2 text-sm font-medium text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200 transition-colors select-none">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={showComparison}
|
||||
onChange={() => setShowComparison((s) => !s)}
|
||||
className="h-4 w-4 rounded border-neutral-300 text-brand-orange focus:ring-brand-orange dark:border-neutral-600 dark:bg-neutral-800 focus:ring-offset-0"
|
||||
/>
|
||||
<span>Compare</span>
|
||||
</label>
|
||||
<Checkbox
|
||||
checked={showComparison}
|
||||
onCheckedChange={setShowComparison}
|
||||
label="Compare"
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{/* Vertical Separator */}
|
||||
|
||||
44
components/ui/Checkbox.tsx
Normal file
44
components/ui/Checkbox.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import React from 'react';
|
||||
import { CheckIcon } from '@radix-ui/react-icons';
|
||||
|
||||
export interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'> {
|
||||
checked?: boolean;
|
||||
onCheckedChange?: (checked: boolean) => void;
|
||||
label?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
|
||||
({ className = '', checked, onCheckedChange, label, disabled, ...props }, ref) => {
|
||||
return (
|
||||
<label className={`inline-flex items-center gap-2 cursor-pointer select-none group ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`}>
|
||||
<div className="relative flex items-center justify-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
ref={ref}
|
||||
className="peer sr-only"
|
||||
checked={checked}
|
||||
onChange={(e) => onCheckedChange?.(e.target.checked)}
|
||||
disabled={disabled}
|
||||
{...props}
|
||||
/>
|
||||
<div className={`
|
||||
w-5 h-5 rounded-md border transition-all duration-200 flex items-center justify-center
|
||||
${checked
|
||||
? 'bg-brand-orange border-brand-orange text-white'
|
||||
: 'bg-white dark:bg-neutral-900 border-neutral-300 dark:border-neutral-700 group-hover:border-brand-orange/50'}
|
||||
peer-focus-visible:ring-2 peer-focus-visible:ring-brand-orange/20 peer-focus-visible:ring-offset-2
|
||||
`}>
|
||||
<CheckIcon className={`w-3.5 h-3.5 transition-transform duration-200 ${checked ? 'scale-100' : 'scale-0'}`} />
|
||||
</div>
|
||||
</div>
|
||||
{label && (
|
||||
<span className="text-sm font-medium text-neutral-600 dark:text-neutral-400 group-hover:text-neutral-900 dark:group-hover:text-neutral-200 transition-colors">
|
||||
{label}
|
||||
</span>
|
||||
)}
|
||||
</label>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Checkbox.displayName = 'Checkbox';
|
||||
Reference in New Issue
Block a user