@@ -7,6 +7,7 @@ import { createDisabledTextStyles, createHatchedBackground } from '../common';
7
7
import { padding , fontSizes } from '../common/system' ;
8
8
import useControlledOrUncontrolled from '../common/hooks/useControlledOrUncontrolled' ;
9
9
import Cutout from '../Cutout/Cutout' ;
10
+ import { StyledListItem } from '../ListItem/ListItem' ;
10
11
11
12
const checkboxSize = 20 ;
12
13
@@ -22,6 +23,11 @@ const StyledLabel = styled.label`
22
23
user-select: none;
23
24
font-size: ${ fontSizes . md } ;
24
25
${ props => props . isDisabled && createDisabledTextStyles ( ) }
26
+
27
+ ${ StyledListItem } & {
28
+ margin: 0;
29
+ height: 100%;
30
+ }
25
31
` ;
26
32
27
33
const StyledInput = styled . input `
@@ -63,6 +69,21 @@ const StyledFlatCheckbox = styled.div`
63
69
background: ${ ( { theme, isDisabled } ) =>
64
70
isDisabled ? theme . flatLight : theme . canvas } ;
65
71
` ;
72
+
73
+ const StyledMenuCheckbox = styled . div `
74
+ position: relative;
75
+ box-sizing: border-box;
76
+ display: inline-block;
77
+ background: ${ ( { theme, isDisabled } ) =>
78
+ isDisabled ? theme . flatLight : theme . canvas } ;
79
+ ${ sharedCheckboxStyles }
80
+ width: ${ checkboxSize - 4 } px;
81
+ height: ${ checkboxSize - 4 } px;
82
+ background: none;
83
+ border: none;
84
+ outline: none;
85
+ ` ;
86
+
66
87
const CheckmarkIcon = styled . span . attrs ( ( ) => ( {
67
88
'data-testid' : 'checkmarkIcon'
68
89
} ) ) `
@@ -84,15 +105,46 @@ const CheckmarkIcon = styled.span.attrs(() => ({
84
105
isDisabled ? theme . checkmarkDisabled : theme . checkmark } ;
85
106
border-width: 0 3px 3px 0;
86
107
transform: translate(-50%, -50%) rotate(45deg);
108
+
109
+ ${ ( { variant, theme, isDisabled } ) =>
110
+ variant === 'menu'
111
+ ? css `
112
+ border-color: ${ isDisabled ? theme . textDisabled : theme . text } ;
113
+ filter: drop-shadow(
114
+ 1px 1px 0px
115
+ ${ isDisabled ? theme . textDisabledShadow : 'transparent' }
116
+ );
117
+ `
118
+ : css `
119
+ border-color: ${ isDisabled
120
+ ? theme . checkmarkDisabled
121
+ : theme . checkmark } ;
122
+ ` }
123
+ ${ StyledListItem } :hover & {
124
+ ${ ( { theme, isDisabled, variant } ) =>
125
+ ! isDisabled &&
126
+ variant === 'menu' &&
127
+ css `
128
+ border-color: ${ theme . textInvert } ;
129
+ ` } ;
87
130
}
88
131
` ;
89
132
const IndeterminateIcon = styled . span . attrs ( ( ) => ( {
90
133
'data-testid' : 'indeterminateIcon'
91
134
} ) ) `
92
135
display: inline-block;
93
136
position: relative;
94
- width: 100%;
95
- height: 100%;
137
+
138
+ ${ ( { variant } ) =>
139
+ variant === 'menu'
140
+ ? css `
141
+ height: calc(100% - 4px);
142
+ width: calc(100% - 4px);
143
+ `
144
+ : css `
145
+ width: 100%;
146
+ height: 100%;
147
+ ` }
96
148
&:after {
97
149
content: '';
98
150
display: block;
@@ -104,10 +156,20 @@ const IndeterminateIcon = styled.span.attrs(() => ({
104
156
createHatchedBackground ( {
105
157
mainColor : isDisabled ? theme . checkmarkDisabled : theme . checkmark
106
158
} ) }
107
- background-position: -1px -1px, 1px 1px;
108
- outline: 1px solid
109
- ${ ( { theme, isDisabled } ) => ( isDisabled ? theme . material : theme . canvas ) } ;
110
- outline-offset: -1px;
159
+ background-position: 0px 0px, 2px 2px;
160
+
161
+ ${ ( { variant, isDisabled, theme } ) =>
162
+ variant === 'menu' &&
163
+ css `
164
+ ${ StyledListItem } :hover & {
165
+ ${ createHatchedBackground ( {
166
+ mainColor : theme . textInvert
167
+ } ) }
168
+ }
169
+ filter: drop-shadow(
170
+ 1px 1px 0px ${ isDisabled ? theme . textDisabledShadow : 'transparent' }
171
+ );
172
+ ` } ;
111
173
}
112
174
` ;
113
175
const LabelText = styled . span `
@@ -139,8 +201,12 @@ const Checkbox = React.forwardRef(function Checkbox(props, ref) {
139
201
setState ( newState ) ;
140
202
if ( onChange ) onChange ( e ) ;
141
203
} ;
142
- const CheckboxComponent =
143
- variant === 'flat' ? StyledFlatCheckbox : StyledCheckbox ;
204
+
205
+ const CheckboxComponent = {
206
+ flat : StyledFlatCheckbox ,
207
+ default : StyledCheckbox ,
208
+ menu : StyledMenuCheckbox
209
+ } [ variant ] ;
144
210
145
211
let Icon = null ;
146
212
if ( indeterminate ) {
@@ -156,7 +222,7 @@ const Checkbox = React.forwardRef(function Checkbox(props, ref) {
156
222
isDisabled = { disabled }
157
223
role = 'presentation'
158
224
>
159
- { Icon && < Icon isDisabled = { disabled } /> }
225
+ { Icon && < Icon isDisabled = { disabled } variant = { variant } /> }
160
226
</ CheckboxComponent >
161
227
{ label && < LabelText > { label } </ LabelText > }
162
228
< StyledInput
@@ -200,7 +266,7 @@ Checkbox.propTypes = {
200
266
label : propTypes . oneOfType ( [ propTypes . string , propTypes . number ] ) ,
201
267
checked : propTypes . bool ,
202
268
disabled : propTypes . bool ,
203
- variant : propTypes . oneOf ( [ 'default' , 'flat' ] ) ,
269
+ variant : propTypes . oneOf ( [ 'default' , 'flat' , 'menu' ] ) ,
204
270
style : propTypes . shape ( [ propTypes . string , propTypes . number ] ) ,
205
271
defaultChecked : propTypes . bool ,
206
272
indeterminate : propTypes . bool ,
0 commit comments