Skip to main content
Glama
checkbox.tsx5.14 kB
import * as React from "react"; import { clsx } from "clsx"; import { twMerge } from "tailwind-merge"; import { CheckboxCheck, CheckboxIntermediate } from "./utils/images"; const checkboxStates = { indeterminate: [ "[&>input:indeterminate~.checkmark>.icon-wrapper]:bg-purple-300 dark:[&>input:indeterminate~.checkmark>.icon-wrapper]:bg-purple-500/50", // Checkmark bg color "[&>input:indeterminate~.checkmark>.icon-wrapper]:border-none", // Checkmark no border "[&>input:indeterminate~.checkmark>.icon-wrapper>.indeterminate-icon]:block", // Show indeterminate icon ], checked: [ "[&>input:checked~.checkmark>.icon-wrapper]:bg-purple-500", // Checkmark bg color "[&>input:checked~.checkmark>.icon-wrapper]:border-none", // Checkmark no border "[&>input:checked~.checkmark>.icon-wrapper>.checkmark-tick]:block", // Show check icon ], focus: [ "[&>input:focus-visible~.checkmark>.icon-wrapper]:ring-4", "[&>input:focus-visible~.checkmark>.icon-wrapper]:ring-ring", "[&>input:focus-visible~.checkmark>.icon-wrapper]:ring-gray-100 dark:[&>input:focus-visible~.checkmark>.icon-wrapper]:ring-gray-100/10", // Focus shadow when unchecked "[&>input:focus-visible:checked~.checkmark>.icon-wrapper]:ring-purple-100 dark:[&>input:focus-visible:checked~.checkmark>.icon-wrapper]:ring-purple-100/10", // Focus shadow when checked "[&>input:focus:indeterminate~.checkmark>.icon-wrapper]:ring-purple-100 dark:[&>input:focus:indeterminate~.checkmark>.icon-wrapper]:ring-purple-100/10", // Focus shadow when indeterminate ], disabled: [ '[&>input[type="checkbox"]:disabled~.checkmark>.icon-wrapper]:border-gray-200', // Checkmark border when unchecked '[&>input[type="checkbox"]:disabled:checked~.checkmark>.icon-wrapper]:bg-gray-200', // Checkmark bg when checked '[&>input[type="checkbox"]:disabled:checked~.checkmark>.icon-wrapper]:text-med-em', // Checkmark bg when checked '[&>input[type="checkbox"]:disabled:indeterminate~.checkmark>.icon-wrapper]:bg-gray-400', // Checkmark bg when indeterminate ], }; interface CheckboxProps extends Omit< React.InputHTMLAttributes<HTMLInputElement>, "size" | "onChange" > { size?: "sm" | "md"; shape?: "square" | "round"; label?: string; caption?: string; indeterminate?: boolean; disabled?: boolean; onChange?: (checked: boolean) => void; } const Checkbox = ({ size = "md", shape = "square", label, caption, className = "", checked, disabled, indeterminate, defaultChecked, onChange, ...rest }: CheckboxProps) => { return ( <label className={twMerge( clsx( "flex gap-3", disabled ? "cursor-not-allowed" : "cursor-pointer", ...checkboxStates["indeterminate"], ...checkboxStates["checked"], ...checkboxStates["focus"], ...checkboxStates["disabled"], className ) )} > <input ref={(input) => { if (input) { defaultChecked && (input.checked = true); indeterminate && (input.indeterminate = true); !indeterminate && (input.indeterminate = false); } }} type="checkbox" className="h-0 w-0 absolute opacity-0 pointer-events-none" onChange={(e: React.ChangeEvent<HTMLInputElement>) => onChange && onChange(e.target.checked) } checked={checked} disabled={disabled} {...rest} /> <div className={clsx( "checkmark", size === "sm" && "p-0.5", size === "md" && "p-[3px]", !disabled && "text-white", disabled && indeterminate && "text-med-em", disabled && !indeterminate && "text-disabled" )} > <div className={clsx( "icon-wrapper", size === "sm" && "h-4 w-4 min-w-4", size === "md" && "h-[18px] w-[18px] min-w-[18px]", "border-2", disabled ? "border-gray-200" : "border-gray-300", shape === "round" ? "rounded-full" : "rounded-md" )} > {indeterminate && ( <CheckboxIntermediate className="indeterminate-icon hidden w-full h-full" /> )} <CheckboxCheck className="checkmark-tick hidden w-full h-full" /> </div> </div> {(label || caption) && ( <div className="flex flex-col gap-0.5 justify-center flex-grow"> {label && ( <p className={clsx( "font-semibold", size === "md" ? "text-sm" : "text-xs", disabled && indeterminate && "text-current", disabled && !indeterminate && "text-gray-300" )} > {label} </p> )} {caption && ( <p className={clsx( "text-xs", disabled ? "text-disabled" : "text-gray-300" )} > {caption} </p> )} </div> )} </label> ); }; export { Checkbox };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mobile-dev-inc/Maestro'

If you have feedback or need assistance with the MCP directory API, please join our Discord server