UNPKG

@axeptio/design-system

Version:
146 lines (124 loc) 3.57 kB
import React, { useRef, useEffect } from 'react'; import styled from 'styled-components'; import PropTypes from 'prop-types'; const sizeList = ['small', 'medium']; const Input = styled.input` position: absolute; clip: rect(0, 0, 0, 0); `; const Label = styled.label` position: relative; display: inline-flex; align-items: center; gap: 8px; font-size: ${props => (props.size === 'small' ? 15 : 16)}px; font-weight: 600; user-select: none; cursor: ${props => (props.disabled ? 'not-allowed' : 'pointer')}; ${props => props.disabled && ` opacity: 0.5; cursor: not-allowed; `}; `; const Indicator = styled.div` position: relative; width: ${props => (props.size === 'small' ? 16 : 20)}px; height: ${props => (props.size === 'small' ? 16 : 20)}px; background-color: ${props => props.theme.colors.white}; border: solid 1.5px ${props => props.theme.colors.grey.v200}; border-radius: ${props => (props.size === 'small' ? '5px' : '6px')}; ${props => props.rounded && ` border-radius: 50%; `}; ${Input}:not(:disabled):checked + & { background-color: ${props => props.theme.checkboxes.default.bgColorChecked}; } ${Label}:hover & { border-color: ${props => props.theme.colors.grey.v300}; } ${Input}:focus + & { box-shadow: 0 0 0 3px ${props => props.theme.colors.grey.v200}; } // Avoid hover on indicator when checkbox is disabled ${Input}:disabled + &, ${Input}:disabled + &:hover { background-color: ${props => props.theme.colors.grey.v100}; border-color: ${props => props.theme.colors.grey.v300}; } &::after { content: ''; position: absolute; display: none; outline: none; } ${Input}:checked + &::after { display: block; position: absolute; width: 5px; height: 10px; margin-top: -0.0625em; top: 50%; left: 50%; transform: translate(-50%, -50%) rotate(45deg); border: solid ${props => props.theme.colors.white}; border-width: 0 2px 2px 0; } ${Input}:indeterminate + & { background: ${props => props.theme.checkboxes.default.bgColorChecked}; &::after { content: ''; position: absolute; display: block; position: absolute; width: 9px; height: 2px; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: ${props => props.theme.colors.white}; } } ${props => props.size === 'small' && ` ${Input}:checked + &::after { width: 4px; height: 8px; border-width: 0 1.5px 1.5px 0; } ${Input}:indeterminate + &::after { width: 7px; height: 1.5px; } `}; `; const Checkbox = ({ indeterminate = false, checked, value, onChange, name, id, label, size, rounded, disabled }) => { const checkboxRef = useRef(); useEffect(() => { checkboxRef.current.indeterminate = indeterminate; }, [checkboxRef, indeterminate]); return ( <Label htmlFor={id} size={size} disabled={disabled}> <Input type="checkbox" id={id} name={name} disabled={disabled} checked={checked} onChange={onChange} ref={checkboxRef} /> <Indicator rounded={rounded} size={size} role="indicator" /> {label} </Label> ); }; Checkbox.propTypes = { value: PropTypes.string, indeterminate: PropTypes.bool, checked: PropTypes.bool, onChange: PropTypes.func, label: PropTypes.string, name: PropTypes.string, id: PropTypes.string, size: PropTypes.oneOf(sizeList), rounded: PropTypes.bool, disabled: PropTypes.bool }; export default Checkbox;