-
Notifications
You must be signed in to change notification settings - Fork 512
/
Checkbox.tsx
129 lines (110 loc) · 3.32 KB
/
Checkbox.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import React from 'react';
import styled, {css, keyframes} from 'styled-components';
import {CheckIcon, PartialCheckIcon} from '../../icons';
const checkTick = keyframes`
to {
stroke-dashoffset: 0;
}
`;
const uncheckTick = keyframes`
to {
stroke-dashoffset: 20px;
}
`;
const Container = styled.div`
display: flex;
`;
const TickIcon = styled(CheckIcon)`
animation: ${uncheckTick} 0.2s ease-in forwards;
opacity: 0;
stroke-dasharray: 0px;
stroke-dashoffset: 0;
transition-delay: 0.2s;
transition: opacity 0.1s ease-out;
`;
const CheckboxContainer = styled.div<{checked: boolean; readOnly: boolean}>`
background-color: transparent;
height: 20px;
width: 20px;
border: 1px solid ${({theme}) => theme.palette.checkbox.borderColor};
border-radius: 3px;
outline: none;
${(props) =>
props.checked &&
css`
background-color: ${({theme}) => theme.palette.checkbox.checked.backgroundColor};
${TickIcon} {
animation-delay: 0.2s;
animation: ${checkTick} 0.2s ease-out forwards;
stroke-dashoffset: 20px;
opacity: 1;
transition-delay: 0s;
}
`}
${(props) =>
props.checked &&
props.readOnly &&
css`
background-color: ${({theme}) => theme.palette.checkbox.checkedAndDisabled.backgroundColor};
border-color: ${({theme}) => theme.palette.checkbox.checkedAndDisabled.borderColor};
`}
${(props) =>
!props.checked &&
props.readOnly &&
css`
background-color: ${({theme}) => theme.palette.checkbox.disabled.backgroundColor};
border-color: ${({theme}) => theme.palette.checkbox.disabled.borderColor};
`}
`;
const LabelContainer = styled.div<{readOnly: boolean}>`
color: ${({theme}) => theme.palette.formLabel.color};
font-weight: 400;
font-size: 15px;
padding-left: 10px;
${(props) =>
props.readOnly &&
css`
color: ${({theme}) => theme.palette.formLabel.disabled.color};
`}
`;
type CheckboxProps = {
/**
* State of the Checkbox
*/
checked: boolean;
/**
* Displays the value of the input, but does not allow changes.s
*/
readOnly?: boolean;
/**
* The undetermined state comes into play when the checkbox contains a sublist of selections,
* some of which are selected, and others aren't.
*/
undetermined?: boolean;
/**
* Provide a description of the Checkbox, the label appears on the right of the checkboxes.
*/
label?: string;
/**
* The handler called when clicking on Checkbox
*/
onChange?: (value: boolean) => void;
};
/**
* The checkboxes are applied when users can select all, several, or none of the options from a given list.
*/
const Checkbox = ({label, checked, onChange, undetermined = false, readOnly = false}: CheckboxProps) => {
if (undefined === onChange && false === readOnly) {
throw new Error('A Checkbox element expect an onChange attribute if not readOnly');
}
const handleChange = () => onChange && !readOnly && onChange(!checked);
return (
<Container onClick={handleChange}>
<CheckboxContainer checked={checked || undetermined} readOnly={readOnly}>
{undetermined ? <PartialCheckIcon height={20} width={20} /> : <TickIcon height={20} width={20} />}
</CheckboxContainer>
{label ? <LabelContainer readOnly={readOnly}>{label}</LabelContainer> : null}
</Container>
);
};
export {Checkbox};