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
81
82
83
84
85
86
87
88
89
90
91
92
93
| import { forwardRef, useCallback, useEffect, useMemo, useState } from "react";
| import clsx from "clsx";
| import { Label } from "@humansignal/ui";
| import styles from "./toggle.module.scss";
|
| type ToggleProps = {
| className?: string;
| label?: string;
| labelProps?: Partial<React.ComponentProps<typeof Label>>;
| description?: string;
| checked?: boolean;
| defaultChecked?: boolean;
| onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
| required?: boolean;
| style?: React.CSSProperties;
| disabled?: boolean;
| alwaysBlue?: boolean;
| };
|
| export const Toggle = forwardRef<HTMLInputElement, ToggleProps>(
| (
| {
| className,
| label,
| labelProps,
| description,
| checked,
| defaultChecked,
| onChange,
| required,
| style,
| alwaysBlue,
| ...props
| },
| ref,
| ) => {
| const initialChecked = useMemo(() => defaultChecked ?? checked ?? false, [defaultChecked, checked]);
| const [isChecked, setIsChecked] = useState<boolean>(defaultChecked ?? checked ?? false);
| useEffect(() => {
| setIsChecked(initialChecked);
| }, [initialChecked]);
|
| const onChangeHandler = useCallback(
| (e: React.ChangeEvent<HTMLInputElement>) => {
| if (typeof checked === "undefined") {
| setIsChecked(e.target.checked);
| }
| onChange?.(e);
| },
| [onChange, checked],
| );
|
| const formField = (
| <div
| className={clsx(
| styles.toggle,
| {
| [styles.toggle_disabled]: props.disabled,
| [styles.toggle_checked]: isChecked,
| [styles.toggle_alwaysBlue]: alwaysBlue,
| },
| className,
| )}
| style={style}
| >
| <input
| {...props}
| ref={ref}
| className={clsx(styles.toggle__input)}
| type="checkbox"
| checked={isChecked}
| onChange={onChangeHandler}
| />
| <span className={clsx(styles.toggle__indicator)} />
| </div>
| );
|
| return label ? (
| <Label
| placement="right"
| required={required}
| text={label}
| description={description}
| className="gap-2"
| {...(labelProps ?? {})}
| >
| {formField}
| </Label>
| ) : (
| formField
| );
| },
| );
|
|