Bin
2025-12-16 9e0b2ba2c317b1a86212f24cbae3195ad1f3dbfa
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
import { type InputHTMLAttributes, useEffect, useRef } from "react";
import { clsx } from "clsx";
import styles from "./checkbox.module.scss";
 
export interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"> {
  indeterminate?: boolean;
  checkboxClassName?: string;
  ariaLabel?: string;
}
 
export const Checkbox = ({
  checked,
  indeterminate,
  style,
  onChange,
  children,
  checkboxClassName,
  ariaLabel,
  ...props
}: CheckboxProps) => {
  const checkboxRef = useRef<HTMLInputElement>();
 
  useEffect(() => {
    if (checkboxRef.current) {
      checkboxRef.current.indeterminate = indeterminate;
    }
  }, [indeterminate]);
 
  const checkboxContent = (
    <span className={clsx(styles.checkbox__box, { [styles.checkbox__box_checked]: checked })}>
      <input
        {...props}
        ref={checkboxRef}
        checked={!!checked}
        className={clsx(styles.checkbox__input, checkboxClassName)}
        type="checkbox"
        onChange={onChange}
        aria-checked={indeterminate ? "mixed" : !!checked}
        aria-label={ariaLabel ?? (typeof children === "string" ? children : "")}
      />
      <span
        className={clsx(styles.checkbox__check, {
          [styles.checkbox__check_checked]: checked,
          [styles.checkbox__check_indeterminate]: indeterminate,
        })}
      />
    </span>
  );
 
  return (
    <div
      className={clsx(styles.checkbox, { [styles.checkbox_disabled]: props.disabled }, props.className)}
      style={style}
    >
      {children ? (
        <label className={styles.checkbox__label}>
          {checkboxContent} {children}
        </label>
      ) : (
        checkboxContent
      )}
    </div>
  );
};
 
export default Checkbox;