37 lines
1.2 KiB
TypeScript
37 lines
1.2 KiB
TypeScript
import { forwardRef, useId } from "react";
|
|
import type { InputHTMLAttributes, ReactNode } from "react";
|
|
import { cn } from "@/lib/utils/cn";
|
|
|
|
export interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"> {
|
|
label: ReactNode;
|
|
description?: ReactNode;
|
|
}
|
|
|
|
/**
|
|
* Native checkbox styled via `accent-*` rather than a hand-drawn box — full
|
|
* built-in keyboard/screen-reader support, no extra ARIA required.
|
|
*/
|
|
export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
|
({ className, label, description, id, ...props }, ref) => {
|
|
const generatedId = useId();
|
|
const checkboxId = id ?? generatedId;
|
|
|
|
return (
|
|
<label htmlFor={checkboxId} className="flex cursor-pointer items-start gap-3">
|
|
<input
|
|
ref={ref}
|
|
type="checkbox"
|
|
id={checkboxId}
|
|
className={cn("mt-1 h-4 w-4 shrink-0 rounded border-line accent-accent", className)}
|
|
{...props}
|
|
/>
|
|
<span>
|
|
<span className="block text-sm font-bold">{label}</span>
|
|
{description && <span className="block text-xs text-muted">{description}</span>}
|
|
</span>
|
|
</label>
|
|
);
|
|
},
|
|
);
|
|
Checkbox.displayName = "Checkbox";
|