-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
/
SwitchUnstyled.tsx
81 lines (73 loc) · 2.39 KB
/
SwitchUnstyled.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
import React, { ComponentPropsWithoutRef, CSSProperties, ElementType } from 'react';
import clsx from 'clsx';
import useSwitch, { UseSwitchProps } from './useSwitch';
import classes from './switchUnstyledClasses';
import ButtonUnstyled from '../ButtonUnstyled/ButtonUnstyled';
export interface SwitchUnstyledProps<
TRoot extends ElementType,
TThumb extends ElementType,
TInput extends ElementType,
> extends UseSwitchProps {
components?: {
Root?: TRoot;
Thumb?: TThumb;
Input?: TInput;
};
componentsProps?: {
root?: ComponentPropsWithoutRef<TRoot>;
thumb?: ComponentPropsWithoutRef<TThumb>;
input?: ComponentPropsWithoutRef<TInput>;
};
}
const minimalRootStyles: CSSProperties = {
position: 'relative',
};
const minimalInputStyles: CSSProperties = {
position: 'absolute',
width: '100%',
height: '100%',
top: 0,
left: 0,
opacity: 0,
zIndex: 1,
margin: 0,
};
const SwitchUnstyled = function SwitchUnstyled<
TRoot extends ElementType = 'span',
TThumb extends ElementType = 'span',
TInput extends ElementType = 'input',
>(props: SwitchUnstyledProps<TRoot, TThumb, TInput>) {
const { components = {}, componentsProps = {}, ...otherProps } = props;
const Root = components.Root ?? 'span';
const rootProps = componentsProps.root ?? ({} as React.ComponentPropsWithoutRef<TRoot>);
const Thumb = components.Thumb ?? 'span';
const thumbProps = componentsProps.thumb ?? ({} as React.ComponentPropsWithoutRef<TThumb>);
const Input = components.Input ?? 'input';
const inputProps = componentsProps.input ?? ({} as React.ComponentPropsWithoutRef<TInput>);
const { getInputProps, isChecked, isDisabled } = useSwitch(otherProps);
const computedClasses = {
[classes.checked]: isChecked,
[classes.disabled]: isDisabled,
};
return (
<Root style={minimalRootStyles} {...rootProps} className={clsx(classes.root, computedClasses)}>
<ButtonUnstyled
components={{ Root: 'span' }}
tabIndex={-1}
disabled={isDisabled}
className={classes.button}
role={undefined}
focusVisibleClassName={classes.focusVisible}
>
<Thumb {...thumbProps} className={classes.thumb} />
<Input
type="checkbox"
style={minimalInputStyles}
{...getInputProps(inputProps)}
className={classes.input}
/>
</ButtonUnstyled>
</Root>
);
};
export default SwitchUnstyled;