-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCheckBox.tsx
More file actions
128 lines (116 loc) · 2.65 KB
/
Copy pathCheckBox.tsx
File metadata and controls
128 lines (116 loc) · 2.65 KB
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
import React, {HTMLAttributes} from 'react'
import {MdCheckBoxOutlineBlank, MdCheckBox} from 'react-icons/md'
import styled from 'styled-components'
import Flex, {AlignItems} from './Flex'
import Text from './Text'
import {assert} from '../../utils'
type Props = {
className?: string
label?: string
labelComponent?: React.ReactNode
labelColor?: string
checked: boolean
disabled?: boolean
onToggle?: (newValue: boolean) => void
checkedColor?: string
size?: string
alignSelf?: AlignItems
} & HTMLAttributes<HTMLElement>
const CheckBox = ({
className,
checkedColor,
disabled,
size,
checked,
label,
labelComponent,
labelColor,
onToggle,
alignSelf,
...props
}: Props) => {
const handleClick = (e: React.MouseEvent) => {
if (disabled || !onToggle) {
e.preventDefault()
return
}
e.preventDefault()
e.stopPropagation()
onToggle(!checked)
}
if (label) {
assert(
!labelComponent,
'Either label or labelComponent must be provided, not both.',
)
} else if (labelComponent) {
assert(!label, 'Either label or labelComponent must be provided, not both.')
}
return (
<WrapperFlex
className={className}
{...props}
alignSelf={alignSelf || 'flex-start'}
gap="8px"
onClick={(e) => handleClick(e)}
disabled={disabled}
>
{checked && (
<CheckedIcon disabled={disabled} size={size} color={checkedColor} />
)}
{!checked && (
<UncheckedIcon disabled={disabled} size={size} color={checkedColor} />
)}
{label && <Label labelColor={labelColor}>{label}</Label>}
{labelComponent}
</WrapperFlex>
)
}
const WrapperFlex = styled(Flex)<{disabled?: boolean}>`
${(props) =>
!props.disabled
? `
&:hover {
cursor: pointer;
}`
: ''}
opacity: ${(props) => (props.disabled ? '0.5' : '1')};
`
const iconStyle = (props: {
disabled?: boolean
size?: string
color?: string
}) => `
width: ${props.size || '18px'};
aspect-ratio: 1;
flex-shrink: 0;
color: ${props.color || 'var(--color-secondary)'};
${
!props.disabled
? `
:hover {
cursor: pointer;
}`
: ''
}
`
const CheckedIcon = styled(MdCheckBox)<{
disabled?: boolean
size?: string
color?: string
}>`
${(props) => iconStyle(props)}
${(props) => (props.color ? `color: ${props.color}` : '')}
`
const UncheckedIcon = styled(MdCheckBoxOutlineBlank)<{
disabled?: boolean
size?: string
}>`
${(props) => iconStyle(props)}
`
const Label = styled(Text)<{labelColor?: string}>`
display: inline;
color: ${(props) =>
props.labelColor ? props.labelColor : 'var(--color-secondary)'};
`
export default CheckBox