All files / react-app/src/components/Inputs checkbox.tsx

100% Statements 8/8
100% Branches 12/12
100% Functions 4/4
100% Lines 6/6

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80          72x                                                                                           72x               72x                 4x 4x 3x                  
import * as React from "react";
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
import { Check } from "lucide-react";
import { cn } from "@/utils";
import { DependencyWrapperProps } from "shared-types";
const Checkbox = React.forwardRef<
  React.ElementRef<typeof CheckboxPrimitive.Root>,
  React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> &
    DependencyWrapperProps & {
      className?: string;
      label?: string;
      value?: string;
      styledLabel?: React.ReactNode;
      description?: string;
      optionlabelClassName?: string;
    }
>(({ className, ...props }, ref) => {
  return (
    <div className="items-top flex space-x-2">
      <CheckboxPrimitive.Root
        ref={ref}
        id={(props.label || props.styledLabel) as string}
        className={cn(
          "peer h-7 w-7 my-2 shrink-0 rounded-sm border-black border-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:border-primary data-[state=checked]:text-primary-foreground",
          className,
        )}
        {...props}
      >
        <CheckboxPrimitive.Indicator className={cn("flex items-center justify-center text-white")}>
          <Check className="h-4 w-4 stroke-[6px]" />
        </CheckboxPrimitive.Indicator>
      </CheckboxPrimitive.Root>
      <div className="grid gap-1.5 leading-none">
        {!!(props.label || props.styledLabel) && (
          <label
            htmlFor={(props.label || props.styledLabel) as string}
            className={cn(
              "mt-2.5 text-md font-normal leading-normal peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
              props.optionlabelClassName,
            )}
          >
            {props.label || props.styledLabel}
          </label>
        )}
        {!!props.description && (
          <p className="text-sm text-muted-foreground">{props.description}</p>
        )}
      </div>
    </div>
  );
});
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
 
type CheckboxGroupProps = {
  value: string[];
  onChange: (value: string[]) => void;
  options: { label: string; value: string }[];
};
 
export const CheckboxGroup = (props: CheckboxGroupProps) => {
  return (
    <div className="flex flex-col gap-2">
      {props.options.map((OPT) => (
        <Checkbox
          key={`CHECK-${OPT.value}`}
          label={OPT.label}
          checked={props.value.includes(OPT.value)}
          onCheckedChange={(c) => {
            const filtered = props.value.filter((f) => f !== OPT.value);
            if (!c) return props.onChange(filtered);
            props.onChange([...filtered, OPT.value]);
          }}
        />
      ))}
    </div>
  );
};
 
export { Checkbox };