Files
RasadDam_Frontend/src/components/Switch/Switch.tsx

99 lines
2.2 KiB
TypeScript
Raw Normal View History

2026-01-19 13:08:58 +03:30
import React from "react";
import clsx from "clsx";
import { bgPrimaryColor, textColor } from "../../data/getColorBasedOnMode";
import { inputWidths } from "../../data/getItemsWidth";
export type SwitchSize = "small" | "medium" | "large";
interface SwitchProps {
checked: boolean;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
disabled?: boolean;
isError?: boolean;
size?: SwitchSize;
label?: string;
name?: string;
className?: string;
}
const sizeMap: Record<
SwitchSize,
{ track: string; thumb: string; thumbTranslate: string }
> = {
small: {
track: "w-9 h-5",
thumb: "w-4 h-4",
thumbTranslate: "translate-x-4",
},
medium: {
track: "w-11 h-6",
thumb: "w-5 h-5",
thumbTranslate: "translate-x-5",
},
large: {
track: "w-14 h-8",
thumb: "w-6 h-6",
thumbTranslate: "translate-x-6",
},
};
export const Switch: React.FC<SwitchProps> = ({
checked,
onChange,
disabled = false,
isError = false,
size = "medium",
label,
name,
className,
}) => {
const sizeStyles = sizeMap[size];
return (
<label
className={clsx(
"inline-flex items-center gap-2 cursor-pointer",
disabled && "opacity-60 cursor-not-allowed",
inputWidths,
className
)}
>
<div className="relative">
<input
type="checkbox"
role="switch"
name={name}
checked={checked}
onChange={onChange}
disabled={disabled}
className="sr-only"
/>
<div
className={clsx(
"rounded-full transition-colors duration-300",
sizeStyles.track,
isError
? checked
? "bg-prima-500"
: "bg-red-300"
: checked
? bgPrimaryColor
: "bg-dark-300"
)}
>
<div
className={clsx(
"absolute top-0.5 left-0.5 rounded-full bg-white shadow transform transition-transform duration-300",
sizeStyles.thumb,
checked && sizeStyles.thumbTranslate
)}
/>
</div>
</div>
{label && (
<span className={`text-sm select-none ${textColor}`}>{label}</span>
)}
</label>
);
};