/
SwitchTrack.tsx
97 lines (91 loc) · 2.46 KB
/
SwitchTrack.tsx
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
94
95
96
97
import type { CSSProperties, HTMLAttributes, InputHTMLAttributes } from "react";
import { forwardRef } from "react";
import cn from "classnames";
import type { PropsWithRef } from "@react-md/utils";
import { bem } from "@react-md/utils";
const styles = bem("rmd-switch");
/** @remarks \@since 2.8.0 */
export interface SwitchTrackProps
extends InputHTMLAttributes<HTMLInputElement> {
/**
* If an `id` is provided, the track will contain a checkbox input element and
* render the "ball" as a `<label>`. If the `id` is omitted, no input element
* will be rendered and the "ball" will be rendered as a `<span>`.
*
* Basically only omit the `id` if this is used in another accessible widget
* like `menuitemcheckbox`.
*/
id?: string;
/**
* An optional style object to provide to the ball.
*/
ballStyle?: CSSProperties;
/**
* An optional class name to provide to the ball.
*/
ballClassName?: string;
/**
* Any additional props and optional ref to provide to the track itself since
* all the props are normally provided to the `<input>` element instead.
*/
containerProps?: PropsWithRef<
HTMLAttributes<HTMLSpanElement>,
HTMLSpanElement
>;
}
/**
* This is most likely an internal only component that is used to render the
* switch element either as a checkbox or in the `MenuItemSwitch` component.
*
* @remarks \@since 2.8.0
*/
export const SwitchTrack = forwardRef<HTMLInputElement, SwitchTrackProps>(
function SwitchTrack(
{
id,
disabled = false,
className,
ballStyle,
ballClassName,
containerProps,
children,
...props
},
ref
) {
const { checked = false } = props;
return (
<span
{...containerProps}
className={cn(styles(), className, containerProps?.className)}
>
{id && (
<>
<input
{...props}
id={id}
ref={ref}
type="checkbox"
className={cn(styles("input"))}
disabled={disabled}
/>
<label
htmlFor={id}
aria-hidden
style={ballStyle}
className={cn(styles("ball"), ballClassName)}
>
{children}
</label>
</>
)}
{!id && (
<span
style={ballStyle}
className={cn(styles("ball", { checked }), ballClassName)}
/>
)}
</span>
);
}
);