generated from react18-tools/turborepo-template
-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
switch.tsx
71 lines (69 loc) · 1.87 KB
/
switch.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
import { HTMLProps } from "react";
import styles from "./switch.module.scss";
import { useStore } from "../../utils";
import { modes } from "../../constants";
export interface SwitchProps extends HTMLProps<HTMLButtonElement> {
/** html tag @defaultValue 'button' */
tag?: "button" | "div";
/** Diameter of the color switch */
size?: number;
/** Skip system colorScheme while toggling */
skipSystem?: boolean;
}
/**
* Switch button to quickly toggle user preference.
*
* @example
* ```tsx
* <Switch [size={20} skipSystem]/>
* ```
*
* @source - Source code
*/
export const Switch = ({
tag: Tag = "button",
size = 24,
skipSystem,
children,
...props
}: SwitchProps) => {
const [state, setState] = useStore();
/** toggle mode */
const handleModeSwitch = () => {
let index = modes.indexOf(state.m);
const n = modes.length;
if (skipSystem && index === n - 1) index = 0;
setState({
...state,
m: modes[(index + 1) % n],
});
};
if (children) {
return (
// @ts-expect-error -- too complex types
<Tag
suppressHydrationWarning
{...props}
data-testid="switch"
// skipcq: JS-0417
onClick={handleModeSwitch}>
{/* @ts-expect-error -> we are setting the CSS variable */}
<div className={styles.switch} style={{ "--size": `${size}px` }} />
{children}
</Tag>
);
}
return (
<Tag
// Hydration warning is caused when the data from localStorage differs from the default data provided while rendering on server
suppressHydrationWarning
{...props}
className={[props.className, styles.switch].join(" ")}
// @ts-expect-error -> we are setting the CSS variable
style={{ "--size": `${size}px` }}
data-testid="switch"
// skipcq: JS-0417 -> tradeoff between size and best practices
onClick={handleModeSwitch}
/>
);
};