import {forwardRef} from 'react'; import styled from '@emotion/styled'; type Props = { toggle: React.MouseEventHandler; className?: string; /** * Toggle color is always active. */ forceActiveColor?: boolean; forwardedRef?: React.Ref; id?: string; isActive?: boolean; isDisabled?: boolean; isLoading?: boolean; name?: string; size?: 'sm' | 'lg'; }; const Switch = ({ forwardedRef, size = 'sm', isActive, forceActiveColor, isLoading, isDisabled, toggle, id, name, className, ...props }: Props) => ( ); type StyleProps = Partial; const getSize = (p: StyleProps) => (p.size === 'sm' ? 16 : 24); const getToggleSize = (p: StyleProps) => getSize(p) - (p.size === 'sm' ? 4 : 8); const getToggleTop = (p: StyleProps) => (p.size === 'sm' ? 1 : 3); const getTranslateX = (p: StyleProps) => p.isActive ? getToggleTop(p) + getSize(p) * 0.875 : getToggleTop(p); const SwitchButton = styled('button')` display: inline-block; background: none; padding: 0; border: 1px solid ${p => p.theme.border}; position: relative; box-shadow: inset ${p => p.theme.dropShadowLight}; height: ${getSize}px; width: ${p => getSize(p) * 1.875}px; border-radius: ${getSize}px; transition: border 0.1s, box-shadow 0.1s; &[disabled] { cursor: not-allowed; } &:focus, &.focus-visible { outline: none; border-color: ${p => p.theme.focusBorder}; box-shadow: ${p => p.theme.focusBorder} 0 0 0 1px; } `; const Toggle = styled('span')` display: block; position: absolute; border-radius: 50%; transition: 0.25s all ease; top: ${getToggleTop}px; transform: translateX(${getTranslateX}px); width: ${getToggleSize}px; height: ${getToggleSize}px; background: ${p => p.isActive || p.forceActiveColor ? p.theme.active : p.theme.border}; opacity: ${p => (p.isDisabled ? 0.4 : null)}; `; export default forwardRef((props, ref) => ( ));