UNPKG

12.7 kBSCSSView Raw
1//
2// Copyright IBM Corp. 2016, 2023
3//
4// This source code is licensed under the Apache-2.0 license found in the
5// LICENSE file in the root directory of this source tree.
6//
7
8@use '../form';
9@use '../../config' as *;
10@use '../../spacing' as *;
11@use '../../theme' as *;
12@use '../../type' as *;
13@use '../../utilities/component-reset';
14@use '../../utilities/convert';
15@use '../../utilities/skeleton' as *;
16@use '../../utilities/visually-hidden' as *;
17
18@mixin checkbox {
19 .#{$prefix}--checkbox-group {
20 @include component-reset.reset;
21 }
22
23 // Spacing between checkboxes
24 .#{$prefix}--form-item.#{$prefix}--checkbox-wrapper {
25 position: relative;
26 margin-block-end: convert.to-rem(6px);
27 }
28
29 // Spacing above collection of checkboxes
30 .#{$prefix}--form-item.#{$prefix}--checkbox-wrapper:first-of-type {
31 margin-block-start: 0;
32 }
33
34 // Shift collection of checkboxes up if label is present
35 // to account for the 2px top margin for the first checkbox
36 .#{$prefix}--label + .#{$prefix}--form-item.#{$prefix}--checkbox-wrapper {
37 margin-block-start: -#{$spacing-01};
38 }
39
40 // Spacing below collection of checkboxes
41 .#{$prefix}--form-item.#{$prefix}--checkbox-wrapper:last-of-type {
42 margin-block-end: convert.to-rem(3px);
43 }
44
45 // Visually, we'll hide the checkbox input and create our own styled version
46 // to match the specs.
47 .#{$prefix}--checkbox {
48 @include visually-hidden;
49 //even though its hidden, positioning is for native validation to be aligned to checkbox
50 inset-block-start: 1.25rem;
51 inset-inline-start: 0.7rem;
52 }
53
54 // The label corresponds to the content inside of the `label` tag. Since we're
55 // creating our own checkbox style, we'll need to position this in order to
56 // accommodate the spacing needed for the checkbox.
57 .#{$prefix}--checkbox-label {
58 @include reset;
59 @include type-style('body-compact-01');
60
61 position: relative;
62 display: flex;
63 cursor: pointer;
64 min-block-size: convert.to-rem(20px);
65 padding-block-start: convert.to-rem(2px);
66 padding-inline-start: convert.to-rem(20px);
67 user-select: none;
68 }
69
70 .#{$prefix}--checkbox-label-text {
71 // Add extra spacing when label is present
72 padding-inline-start: convert.to-rem(10px);
73 }
74
75 // Required because `$css--reset: true` cannot currently apply to this `::before` and `::after`
76 .#{$prefix}--checkbox-label::before,
77 .#{$prefix}--checkbox-label::after {
78 box-sizing: border-box;
79
80 @media print {
81 print-color-adjust: exact;
82 }
83 }
84
85 // Spacing for presentational checkbox
86 .#{$prefix}--checkbox-label::before {
87 // We need to position the pseudo-element absolutely in the space that we've
88 // created with the padding from the label itself. We position only with
89 // `top` since we don't want the checkbox to be centered vertically with the
90 // text overflows.
91 position: absolute;
92 border: 1px solid $icon-primary;
93 border-radius: 2px;
94
95 // Checkboxes with a background color look visually off against a parent container.
96 background-color: transparent;
97 block-size: convert.to-rem(16px);
98 content: '';
99
100 // According to the spec, we'll want the bounding box for our checkbox to
101 // be 16px. The border size will be what will be updated during the
102 // different checkbox states.
103 inline-size: convert.to-rem(16px);
104 inset-block-start: convert.to-rem(2px);
105 inset-inline-start: 0;
106
107 // increase left margin for #6480
108 margin-block: convert.to-rem(1px) convert.to-rem(2px);
109 margin-inline: convert.to-rem(3px) 0;
110 }
111
112 // Create the appearance of the check in the `after` pseudo-element
113 .#{$prefix}--checkbox-label::after {
114 position: absolute;
115 background: none;
116 block-size: convert.to-rem(5px);
117 border-block-end: 1.5px solid $icon-inverse;
118 border-inline-start: 1.5px solid $icon-inverse;
119 content: '';
120 inline-size: convert.to-rem(9px);
121 inset-block-start: convert.to-rem(6.5px);
122 inset-inline-start: convert.to-rem(7px);
123 margin-block-start: convert.to-rem(-3px);
124 transform: scale(0) rotate(-45deg);
125 transform-origin: bottom right;
126 }
127
128 //----------------------------------------------
129 // Checked
130 // ---------------------------------------------
131
132 // Update properties for checked checkbox
133 .#{$prefix}--checkbox:checked + .#{$prefix}--checkbox-label::before,
134 .#{$prefix}--checkbox:indeterminate + .#{$prefix}--checkbox-label::before,
135 .#{$prefix}--checkbox-label[data-contained-checkbox-state='true']::before {
136 border: none;
137 border-width: 1px;
138 background-color: $icon-primary;
139 }
140
141 // Display the check
142 .#{$prefix}--checkbox:checked + .#{$prefix}--checkbox-label::after,
143 .#{$prefix}--checkbox-label[data-contained-checkbox-state='true']::after {
144 transform: scale(1) rotate(-45deg);
145 }
146
147 // Indeterminate symbol
148 .#{$prefix}--checkbox:indeterminate + .#{$prefix}--checkbox-label::after {
149 border-block-end: 2px solid $icon-inverse;
150 border-inline-start: 0 solid $icon-inverse;
151 inline-size: convert.to-rem(8px);
152 inset-block-start: convert.to-rem(11px);
153 transform: scale(1) rotate(0deg);
154 }
155
156 //----------------------------------------------
157 // Focus
158 // ---------------------------------------------
159
160 // Unchecked
161 .#{$prefix}--checkbox:focus + .#{$prefix}--checkbox-label::before,
162 .#{$prefix}--checkbox-label__focus::before,
163 // Checked
164 .#{$prefix}--checkbox:checked:focus + .#{$prefix}--checkbox-label::before,
165 .#{$prefix}--checkbox-label[data-contained-checkbox-state='true'].#{$prefix}--checkbox-label__focus::before,
166 // Indeterminate
167 .#{$prefix}--checkbox:indeterminate:focus + .#{$prefix}--checkbox-label::before {
168 outline: 2px solid $focus;
169 outline-offset: 1px;
170 }
171
172 //----------------------------------------------
173 // Disabled
174 // ---------------------------------------------
175
176 .#{$prefix}--checkbox:disabled + .#{$prefix}--checkbox-label,
177 .#{$prefix}--checkbox-label[data-contained-checkbox-disabled='true'] {
178 color: $text-disabled;
179 cursor: not-allowed;
180 }
181
182 .#{$prefix}--checkbox:disabled + .#{$prefix}--checkbox-label::before,
183 .#{$prefix}--checkbox-label[data-contained-checkbox-disabled='true']::before {
184 border-color: $icon-disabled;
185 }
186
187 .#{$prefix}--checkbox:checked:disabled + .#{$prefix}--checkbox-label::before,
188 .#{$prefix}--checkbox:indeterminate:disabled
189 + .#{$prefix}--checkbox-label::before,
190 .#{$prefix}--checkbox-label[data-contained-checkbox-state='true'][data-contained-checkbox-disabled='true']::before {
191 background-color: $icon-disabled;
192 }
193
194 //----------------------------------------------
195 // Invalid + warn
196 // ---------------------------------------------
197 .#{$prefix}--checkbox-group[data-invalid] .#{$prefix}--checkbox-label::before,
198 .#{$prefix}--checkbox-wrapper--invalid .#{$prefix}--checkbox-label::before,
199 .#{$prefix}--checkbox-wrapper--invalid
200 .#{$prefix}--checkbox:checked
201 + .#{$prefix}--checkbox-label::before {
202 border: 1px solid $support-error;
203 }
204
205 // checkbox group overrides for individual validation checkbox
206 .#{$prefix}--checkbox-group
207 .#{$prefix}--checkbox-wrapper--invalid
208 > .#{$prefix}--checkbox__validation-msg,
209 .#{$prefix}--checkbox-group
210 .#{$prefix}--checkbox-wrapper--warning
211 > .#{$prefix}--checkbox__validation-msg,
212 .#{$prefix}--checkbox-group
213 .#{$prefix}--checkbox-wrapper
214 > .#{$prefix}--form__helper-text {
215 display: none;
216 }
217
218 .#{$prefix}--checkbox-group:not(.#{$prefix}--checkbox-group[data-invalid])
219 .#{$prefix}--checkbox-wrapper--invalid
220 .#{$prefix}--checkbox-label::before,
221 .#{$prefix}--checkbox-group:not(.#{$prefix}--checkbox-group[data-invalid])
222 .#{$prefix}--checkbox-wrapper--invalid
223 .#{$prefix}--checkbox:checked
224 + .#{$prefix}--checkbox-label::before {
225 border: 1px solid $icon-primary;
226 }
227
228 .#{$prefix}--checkbox-group__validation-msg,
229 .#{$prefix}--checkbox__validation-msg {
230 display: none;
231 align-items: flex-start;
232 margin-block-start: $spacing-02;
233 }
234
235 .#{$prefix}--checkbox__invalid-icon {
236 margin: convert.to-rem(1px) convert.to-rem(1px) 0 convert.to-rem(3px);
237 fill: $support-error;
238 min-inline-size: convert.to-rem(16px);
239 }
240
241 .#{$prefix}--checkbox__invalid-icon--warning {
242 fill: $support-warning;
243 }
244
245 .#{$prefix}--checkbox__invalid-icon--warning path:first-of-type {
246 fill: #000000;
247 }
248
249 .#{$prefix}--checkbox-group--invalid
250 .#{$prefix}--checkbox-group__validation-msg,
251 .#{$prefix}--checkbox-group--warning
252 .#{$prefix}--checkbox-group__validation-msg,
253 .#{$prefix}--checkbox-wrapper--invalid
254 > .#{$prefix}--checkbox__validation-msg,
255 .#{$prefix}--checkbox-wrapper--warning
256 > .#{$prefix}--checkbox__validation-msg {
257 display: flex;
258 }
259
260 .#{$prefix}--checkbox-group--invalid
261 .#{$prefix}--checkbox-group__validation-msg
262 .#{$prefix}--form-requirement,
263 .#{$prefix}--checkbox-group--warning
264 .#{$prefix}--checkbox-group__validation-msg
265 .#{$prefix}--form-requirement,
266 .#{$prefix}--checkbox-wrapper--invalid
267 .#{$prefix}--checkbox__validation-msg
268 .#{$prefix}--form-requirement,
269 .#{$prefix}--checkbox-wrapper--warning
270 .#{$prefix}--checkbox__validation-msg
271 .#{$prefix}--form-requirement {
272 display: block;
273 overflow: visible;
274 margin-block-start: 0;
275 margin-inline-start: $spacing-03;
276 max-block-size: 100%;
277 }
278
279 .#{$prefix}--checkbox-group--invalid
280 .#{$prefix}--checkbox-group__validation-msg
281 .#{$prefix}--form-requirement,
282 .#{$prefix}--checkbox-wrapper--invalid
283 .#{$prefix}--checkbox__validation-msg
284 .#{$prefix}--form-requirement {
285 color: $text-error;
286 }
287
288 //----------------------------------------------
289 // Read-only
290 // ---------------------------------------------
291 .#{$prefix}--checkbox-group--readonly .#{$prefix}--checkbox-label,
292 .#{$prefix}--checkbox-wrapper--readonly .#{$prefix}--checkbox-label {
293 cursor: default;
294 }
295
296 .#{$prefix}--checkbox-group--readonly .#{$prefix}--checkbox-label-text,
297 .#{$prefix}--checkbox-wrapper--readonly .#{$prefix}--checkbox-label-text {
298 cursor: text;
299 user-select: text;
300 }
301
302 .#{$prefix}--checkbox-group--readonly
303 .#{$prefix}--checkbox
304 + .#{$prefix}--checkbox-label::before,
305 .#{$prefix}--checkbox-wrapper--readonly
306 .#{$prefix}--checkbox
307 + .#{$prefix}--checkbox-label::before {
308 border-color: $icon-disabled;
309 }
310
311 .#{$prefix}--checkbox-group--readonly
312 .#{$prefix}--checkbox:checked
313 + .#{$prefix}--checkbox-label::before,
314 .#{$prefix}--checkbox-wrapper--readonly
315 .#{$prefix}--checkbox:checked
316 + .#{$prefix}--checkbox-label::before {
317 border: 1px solid $icon-disabled;
318 background: transparent;
319 }
320
321 .#{$prefix}--checkbox-group--readonly
322 .#{$prefix}--checkbox:checked
323 + .#{$prefix}--checkbox-label::after,
324 .#{$prefix}--checkbox-wrapper--readonly
325 .#{$prefix}--checkbox:checked
326 + .#{$prefix}--checkbox-label::after {
327 border-color: $text-primary;
328 }
329
330 //-----------------------------------------------
331 // Skeleton
332 //-----------------------------------------------
333 .#{$prefix}--checkbox-skeleton .#{$prefix}--checkbox-label {
334 cursor: default;
335 }
336
337 .#{$prefix}--checkbox-label-text.#{$prefix}--skeleton {
338 @include skeleton;
339
340 // Add extra spacing when label is present
341 block-size: $spacing-05;
342 inline-size: convert.to-rem(100px);
343 margin-block: convert.to-rem(1px) 0;
344 margin-inline: convert.to-rem(6px) 0;
345 }
346
347 //-----------------------------------------------
348 // InlineCheckbox
349 //-----------------------------------------------
350 .#{$prefix}--checkbox--inline {
351 position: relative;
352 }
353
354 // RTL overrides
355 [dir='rtl'] .#{$prefix}--checkbox-label::after {
356 margin-block-start: 0;
357 margin-inline-start: convert.to-rem(-1px);
358 transform-origin: center;
359 }
360
361 [dir='rtl']
362 .#{$prefix}--checkbox:checked
363 + .#{$prefix}--checkbox-label::after,
364 [dir='rtl']
365 .#{$prefix}--checkbox-label[data-contained-checkbox-state='true']::after {
366 transform: scale(1.2) rotate3d(0.5, 1, 0, 158deg);
367 }
368
369 // Slug styles
370 .#{$prefix}--checkbox-group--slug legend.#{$prefix}--label,
371 .#{$prefix}--checkbox-wrapper--slug .#{$prefix}--checkbox-label-text {
372 display: flex;
373 }
374
375 .#{$prefix}--checkbox-group--slug legend.#{$prefix}--label .#{$prefix}--slug,
376 .#{$prefix}--checkbox-wrapper--slug
377 .#{$prefix}--checkbox-label-text
378 .#{$prefix}--slug {
379 margin-inline-start: $spacing-03;
380 }
381
382 .#{$prefix}--checkbox-wrapper--slug
383 .#{$prefix}--checkbox-label-text
384 .#{$prefix}--slug__button--inline {
385 line-height: inherit;
386 margin-block-start: convert.to-rem(-1px);
387 }
388}