pleroma/app/soapbox/components/ui/toggle/toggle.tsx

55 lines
1.5 KiB
TypeScript
Raw Normal View History

2023-03-31 09:06:43 -07:00
import clsx from 'clsx';
import React, { useRef } from 'react';
2023-03-31 09:50:32 -07:00
interface IToggle extends Pick<React.InputHTMLAttributes<HTMLInputElement>, 'id' | 'name' | 'checked' | 'onChange' | 'required' | 'disabled'> {
2023-03-31 09:15:48 -07:00
size?: 'sm' | 'md'
2023-03-31 09:06:43 -07:00
}
2023-03-31 09:18:45 -07:00
/** A glorified checkbox. */
2023-03-31 09:50:32 -07:00
const Toggle: React.FC<IToggle> = ({ id, size = 'md', name, checked, onChange, required, disabled }) => {
2023-03-31 09:06:43 -07:00
const input = useRef<HTMLInputElement>(null);
const handleClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {
e.preventDefault();
input.current?.focus();
input.current?.click();
};
return (
2023-03-31 09:06:43 -07:00
<button
className={clsx('flex-none rounded-full', {
2023-03-31 09:47:41 -07:00
'bg-gray-500': !checked && !disabled,
'bg-primary-600': checked && !disabled,
'bg-gray-200': !checked && disabled,
'bg-primary-200': checked && disabled,
2023-03-31 09:15:48 -07:00
'w-9 p-0.5': size === 'sm',
'w-11 p-0.5': size === 'md',
2023-03-31 09:47:41 -07:00
'cursor-default': disabled,
2023-03-31 09:15:48 -07:00
})}
2023-03-31 09:06:43 -07:00
onClick={handleClick}
>
2023-03-31 09:15:48 -07:00
<div className={clsx('rounded-full bg-white transition-transform', {
'h-4.5 w-4.5': size === 'sm',
'translate-x-3': size === 'sm' && checked,
'h-6 w-6': size === 'md',
'translate-x-4': size === 'md' && checked,
})}
/>
2023-03-31 09:06:43 -07:00
<input
id={id}
ref={input}
2023-03-31 09:50:32 -07:00
name={name}
2023-03-31 09:06:43 -07:00
type='checkbox'
className='sr-only'
checked={checked}
onChange={onChange}
required={required}
2023-03-31 09:47:41 -07:00
disabled={disabled}
2023-03-31 09:06:43 -07:00
/>
</button>
);
};
export default Toggle;