feat: add user centric features
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* Checkbox — themed replacement for the native `<input type="checkbox" />`.
|
||||
*
|
||||
* The native control is rendered visually hidden (sr-only) so screen
|
||||
* readers and keyboard focus still work the way browsers expect, while
|
||||
* we paint a small rounded box next to it that fills with the primary
|
||||
* color when checked. Fully controlled — caller owns `checked` state.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* <Checkbox checked={ok} onCheckedChange={setOk} />
|
||||
*
|
||||
* <label className="flex items-center gap-2">
|
||||
* <Checkbox checked={ok} onCheckedChange={setOk} />
|
||||
* Accept terms
|
||||
* </label>
|
||||
*/
|
||||
|
||||
import { Check } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export function Checkbox({
|
||||
checked,
|
||||
onCheckedChange,
|
||||
disabled,
|
||||
className,
|
||||
ariaLabel,
|
||||
}: {
|
||||
checked: boolean;
|
||||
onCheckedChange: (next: boolean) => void;
|
||||
disabled?: boolean;
|
||||
className?: string;
|
||||
ariaLabel?: string;
|
||||
}) {
|
||||
return (
|
||||
<span
|
||||
className={cn(
|
||||
"relative inline-flex items-center justify-center shrink-0",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={checked}
|
||||
disabled={disabled}
|
||||
aria-label={ariaLabel}
|
||||
onChange={(e) => onCheckedChange(e.target.checked)}
|
||||
className="peer absolute inset-0 size-full appearance-none m-0 cursor-pointer disabled:cursor-not-allowed rounded-md"
|
||||
/>
|
||||
<span
|
||||
aria-hidden
|
||||
className={cn(
|
||||
"pointer-events-none size-5 rounded-md border transition-colors",
|
||||
"flex items-center justify-center",
|
||||
checked
|
||||
? "bg-primary border-primary"
|
||||
: "bg-background border-border",
|
||||
"peer-hover:border-foreground/40",
|
||||
"peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-1 peer-focus-visible:ring-offset-background",
|
||||
disabled && "opacity-50",
|
||||
)}
|
||||
>
|
||||
{checked ? (
|
||||
<Check className="size-3.5 text-primary-foreground" strokeWidth={3} />
|
||||
) : null}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user