83 lines
1.8 KiB
TypeScript
83 lines
1.8 KiB
TypeScript
import React from "react";
|
|
import styled from "styled-components";
|
|
import { colors } from "@theme/colors";
|
|
|
|
const Container = styled.label`
|
|
display: block;
|
|
position: relative;
|
|
padding-left: 2rem;
|
|
cursor: pointer;
|
|
font-size: 1.5rem; /* 24px */
|
|
user-select: none;
|
|
|
|
/* On mouse-over, add a grey background color */
|
|
&:hover input ~ .custom-cbox {
|
|
background-color: #d4d0c7; /* grey1 */
|
|
}
|
|
`;
|
|
|
|
/* Hide the browser's default checkbox */
|
|
const HiddenDefaultElement = styled.input`
|
|
position: absolute;
|
|
opacity: 0;
|
|
height: 0;
|
|
width: 0;
|
|
`;
|
|
|
|
/* Create a custom checkbox */
|
|
const CustomCBoxElement = styled.span<{checked?: boolean}>`
|
|
border-radius: 4px;
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
height: 1em;
|
|
width: 1em;
|
|
background-color: ${(props) => (props.checked ? colors.blue1 : colors.grey2)};
|
|
|
|
&:focus &:before {
|
|
transition: box-shadow 150ms ease;
|
|
content: '';
|
|
display: block;
|
|
position: absolute;
|
|
top: -4px;
|
|
bottom: -4px;
|
|
left: -4px;
|
|
right: -4px;
|
|
border-radius: 6px;
|
|
border: 2px solid ${colors.blue1};
|
|
}
|
|
`;
|
|
|
|
const Checkmark = styled.div`
|
|
position: absolute;
|
|
left: 0.375em;
|
|
top: calc(0.25em - 1px);
|
|
width: 0.25em;
|
|
height: 0.5em;
|
|
border: solid #fff;
|
|
border-width: 0 0.125em 0.125em 0;
|
|
transform: rotate(45deg);
|
|
`;
|
|
|
|
type CheckboxProps = Omit<
|
|
React.InputHTMLAttributes<HTMLInputElement>,
|
|
"type"
|
|
>;
|
|
|
|
const Checkbox: React.FC<CheckboxProps> = ({ children, checked, ...props }) => (
|
|
<Container>
|
|
{children}
|
|
<HiddenDefaultElement
|
|
type="checkbox"
|
|
checked={checked}
|
|
{...props}
|
|
tabIndex={-1}
|
|
/>
|
|
<CustomCBoxElement tabIndex={0} checked={checked} className="custom-cbox">
|
|
{checked && (<Checkmark />)}
|
|
</CustomCBoxElement>
|
|
</Container>
|
|
);
|
|
|
|
export default Checkbox;
|