@axeptio/design-system
Version:
Design System for Axeptio
146 lines (124 loc) • 3.57 kB
JSX
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;