frigate/web/src/components/Switch.jsx

63 lines
1.9 KiB
React
Raw Normal View History

2021-01-09 20:26:46 +03:00
import { h } from 'preact';
import { useCallback, useState } from 'preact/hooks';
2021-02-02 07:28:25 +03:00
export default function Switch({ checked, id, onChange }) {
const [internalState, setInternalState] = useState(checked);
const [isFocused, setFocused] = useState(false);
const [isHovered, setHovered] = useState(false);
const handleChange = useCallback(
(event) => {
if (onChange) {
onChange(id, !checked);
}
},
[id, onChange, checked]
);
const handleFocus = useCallback(() => {
onChange && setFocused(true);
}, [onChange, setFocused]);
const handleBlur = useCallback(() => {
onChange && setFocused(false);
}, [onChange, setFocused]);
2021-01-09 20:26:46 +03:00
return (
2021-02-02 07:28:25 +03:00
<label
for={id}
className={`flex items-center justify-center ${onChange ? 'cursor-pointer' : 'cursor-not-allowed'}`}
>
<div
onmouseover={handleFocus}
onmouseout={handleBlur}
className={`w-8 h-5 relative ${!onChange ? 'opacity-60' : ''}`}
>
<div className="relative overflow-hidden">
<input
className="absolute left-48"
onBlur={handleBlur}
onFocus={handleFocus}
tabindex="0"
id={id}
type="checkbox"
onChange={handleChange}
checked={checked}
/>
</div>
<div
2021-02-02 07:28:25 +03:00
className={`w-8 h-3 absolute top-1 left-1 ${
!checked ? 'bg-gray-300' : 'bg-blue-300'
} rounded-full shadow-inner`}
/>
2021-01-09 20:26:46 +03:00
<div
2021-02-02 07:28:25 +03:00
className={`transition-all absolute w-5 h-5 rounded-full shadow-md inset-y-0 left-0 ring-opacity-30 ${
isFocused ? 'ring-4 ring-gray-500' : ''
} ${checked ? 'bg-blue-600' : 'bg-white'} ${isFocused && checked ? 'ring-blue-500' : ''}`}
2021-01-09 20:26:46 +03:00
style={checked ? 'transform: translateX(100%);' : 'transform: translateX(0%);'}
/>
</div>
</label>
);
}