Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

USWDS - Checkbox + Radio: create background color variable. #4199

Merged
merged 18 commits into from Jun 7, 2021
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 41 additions & 0 deletions src/components/checkbox/checkbox--test.njk
@@ -0,0 +1,41 @@
<fieldset class="usa-fieldset">
<legend class="usa-legend">Select any historical figure</legend>
<div class="usa-checkbox">
<input class="usa-checkbox__input usa-checkbox__input--tile" id="check-historical-truth-2" type="checkbox" name="historical-figures-2" value="sojourner-truth" checked>
<label class="usa-checkbox__label" for="check-historical-truth-2">Sojourner Truth <span class="usa-checkbox__label-description">This is optional text that can be used to describe the label in more detail.</span></label>
</div>
<div class="usa-checkbox">
<input class="usa-checkbox__input usa-checkbox__input--tile" id="check-historical-douglass-2" type="checkbox" name="historical-figures-2" value="frederick-douglass">
<label class="usa-checkbox__label" for="check-historical-douglass-2">Frederick Douglass</label>
</div>
<div class="usa-checkbox">
<input class="usa-checkbox__input usa-checkbox__input--tile" id="check-historical-washington-2" type="checkbox" name="historical-figures-2" value="booker-t-washington">
<label class="usa-checkbox__label" for="check-historical-washington-2">Booker T. Washington</label>
</div>
<div class="usa-checkbox">
<input class="usa-checkbox__input usa-checkbox__input--tile" id="check-historical-carver-2" type="checkbox" name="historical-figures-2" value="george-washington-carver" disabled>
<label class="usa-checkbox__label" for="check-historical-carver-2">George Washington Carver</label>
</div>
</fieldset>

<div class="checkbox-tests margin-top-4">
<fieldset class="usa-fieldset">
<legend class="usa-legend">Select any historical figure</legend>
<div class="usa-checkbox">
<input class="usa-checkbox__input usa-checkbox__input--tile" id="check-historical-truth-3" type="checkbox" name="historical-figures-3" value="sojourner-truth" checked>
<label class="usa-checkbox__label" for="check-historical-truth-3">Sojourner Truth <span class="usa-checkbox__label-description">This is optional text that can be used to describe the label in more detail.</span></label>
</div>
<div class="usa-checkbox">
<input class="usa-checkbox__input usa-checkbox__input--tile" id="check-historical-douglass-3" type="checkbox" name="historical-figures-3" value="frederick-douglass">
<label class="usa-checkbox__label" for="check-historical-douglass-3">Frederick Douglass</label>
</div>
<div class="usa-checkbox">
<input class="usa-checkbox__input usa-checkbox__input--tile" id="check-historical-washington-3" type="checkbox" name="historical-figures-3" value="booker-t-washington">
<label class="usa-checkbox__label" for="check-historical-washington-3">Booker T. Washington</label>
</div>
<div class="usa-checkbox">
<input class="usa-checkbox__input usa-checkbox__input--tile" id="check-historical-carver-3" type="checkbox" name="historical-figures-3" value="george-washington-carver" disabled>
<label class="usa-checkbox__label" for="check-historical-carver-3">George Washington Carver</label>
</div>
</fieldset>
</div>
2 changes: 1 addition & 1 deletion src/components/checkbox/checkbox.config.yml
@@ -1 +1 @@
preview: "@uswds-form"
preview: "@uswds-framed"
311 changes: 206 additions & 105 deletions src/stylesheets/elements/form-controls/_checkbox-and-radio.scss
@@ -1,3 +1,137 @@
@mixin format-input {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added these two mixins to improve the readability of the component code.

Before:

.usa-checkbox__input:disabled + .usa-checkbox__label::before,
.usa-radio__input:disabled + .usa-radio__label::before {
  background: color("disabled-light");
  box-shadow: 0 0 0 units($theme-input-select-border-width) color("disabled");
  cursor: not-allowed;
}

After:

.usa-checkbox__input,
.usa-radio__input {
  &:disabled {
    @include format-input {
        background: color("disabled-light");
        box-shadow: 0 0 0 units($theme-input-select-border-width) color("disabled");
        cursor: not-allowed;
    }
  }
}

& + [class$="__label"]::before {
@content;
}
}

@mixin format-label {
& + [class$="__label"] {
@content;
}
}

@mixin checkbox-and-radio-colors(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This long mixin allows users to write scoped colors.

It takes two color token inputs, $bg-color and checked-color. Neither are required and will assume the values in settings if omitted. It returns all the code necessary to set checkbox and radio inputs for the desired scope.

For instance, if you wanted to change the color of all checkbox and radio elements within a .checkbox-tests container, you could do something like the following

.checkbox-tests {
  @include set-text-and-bg("green-80");
  @include checkbox-and-radio-colors("green-80", "green-warm-10v");
  padding: units(2);
  border-radius: radius("md");
}

$bg-color: $theme-input-background-color,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bg-color default the component bg color from settings...

$selected-color: "default"
) {
$input-text-color: get-color-token-from-bg($bg-color);
$input-bg-color: if(
$bg-color == "default",
$theme-body-background-color,
$bg-color
);
$input-active-color: nth(
get-link-tokens-from-bg($bg-color, $preferred-link-token: $selected-color),
1
);
$input-disabled-alpha: -0.7;
$input-disabled-alpha--strong: -0.5;
$input-disabled-alpha--weak: -0.8;
$input-border-alpha: -0;
$color-input-disabled: adjust-color(
color($input-text-color),
$alpha: $input-disabled-alpha
);
$color-input-disabled--strong: adjust-color(
color($input-text-color),
$alpha: $input-disabled-alpha--strong
);
$color-input-disabled--weak: adjust-color(
color($input-text-color),
$alpha: $input-disabled-alpha--weak
);
$input-darkmode: if(lightness(color($input-bg-color)) < 50%, true, false);
$input-checkmark: if($input-darkmode, "correct8-alt", "correct8");

.usa-checkbox,
.usa-radio {
background: color($input-bg-color);
}

.usa-checkbox__label,
.usa-radio__label {
color: color($input-text-color);
&::before {
background: color($input-bg-color);
box-shadow: 0 0 0 units($theme-input-select-border-width)
adjust-color(color($input-text-color), $alpha: $input-border-alpha);
}
}
.usa-checkbox__input,
.usa-radio__input {
&:checked {
@include format-input {
background-color: color($input-active-color);
box-shadow: 0 0 0 units($theme-input-select-border-width)
color($input-active-color);
}
}
&:disabled {
@include format-label {
color: $color-input-disabled;
}
@include format-input {
background-color: color($input-bg-color);
box-shadow: 0 0 0 units($theme-input-select-border-width)
$color-input-disabled;
}
}
&--tile {
@include format-label {
background-color: color($input-bg-color);
border: units($theme-input-tile-border-width) solid
$color-input-disabled;
color: color($input-text-color);
}
&:checked {
@include format-label {
background-color: adjust-color(
color($input-active-color),
$alpha: -0.9
);
border-color: color($input-active-color);
}
}
&:disabled:checked {
@include format-label {
background-color: color($input-bg-color);
border-color: $color-input-disabled;
}
}
}
}
.usa-checkbox__input {
&:checked,
&:checked:disabled {
@include format-input {
@include add-background-svg($input-checkmark);
}
}
&:checked:disabled {
@include format-input {
background-color: $color-input-disabled;
}
}
}
.usa-radio__input {
&:checked {
@include format-input {
box-shadow: 0 0 0 units($theme-input-select-border-width)
color($input-active-color),
inset 0 0 0 units($theme-input-select-border-width)
color($input-bg-color);
}
}
&:checked:disabled {
@include format-input {
background-color: $color-input-disabled--weak;
box-shadow: 0 0 0 2px $color-input-disabled,
inset 0 0 0 2px color($input-bg-color);
}
}
}
}

@include override-prose {
.usa-input-list {
@include add-list-reset;
Expand All @@ -11,18 +145,65 @@
}
}

@include checkbox-and-radio-colors;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, I'm using the mixin to set the component's default colors.


.usa-checkbox__input,
.usa-radio__input {
// The actual input element is only visible to screen readers, because
// all visual styling is done via the label.
@include sr-only();

.lt-ie9 & {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this IE9-specific code because we no longer support IE9

border: 0;
float: left;
margin: units(0.5) units(0.5) 0 0;
position: static;
width: auto;
&:focus {
@include format-input {
@include focus-outline(null, null, null, 0.5);
}
}

&:disabled {
@include format-input {
cursor: not-allowed;
}
@include format-label {
cursor: not-allowed;
}
}

// Checkboxes and radios with tap-friendly targets
&--tile {
@include format-label {
border-radius: radius($theme-input-tile-border-radius);
margin-top: units(1);
padding: units(1.5) units(2) units(1.5) units(5);
}
}
}

.usa-radio__input {
&:checked {
@include format-input {
@media print {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Print styles remain as-is regardless of custom color settings.

box-shadow: inset 0 0 0 units($theme-input-select-border-width)
color("white"),
inset 0 0 0 units(2) color("primary"),
0 0 0 units($theme-input-select-border-width) color("primary");
}
}
}
}

.usa-checkbox__input {
&:checked,
&:checked:disabled {
@include format-input {
background-position: center center;
background-size: units(1.5) auto;
@media print {
background-image: none;
background-color: color("white");
content: url("#{$theme-image-path}/checkbox-check-print.svg");
text-indent: 0;
}
}
}
}

Expand All @@ -35,17 +216,18 @@
padding-left: units($input-select-margin-right + $theme-input-select-size);
position: relative;
text-indent: units(-$input-select-margin-right - $theme-input-select-size);
}

.usa-checkbox__label::before,
.usa-radio__label::before {
background: color("white");
content: " ";
display: inline-block;
left: units($theme-input-select-border-width);
position: relative;
vertical-align: middle\0; // Target IE 11 and below to vertically center inputs
white-space: pre;
&:before {
content: " ";
display: inline-block;
left: units($theme-input-select-border-width);
line-height: units($theme-input-select-size);
margin-right: units($input-select-margin-right);
position: relative;
text-indent: 0;
vertical-align: middle\0; // Target IE 11 and below to vertically center inputs
white-space: pre;
}
}

.usa-checkbox__label::before {
Expand All @@ -57,99 +239,18 @@
@include u-circle($theme-input-select-size);
}

.usa-checkbox__label::before,
.usa-radio__label::before {
box-shadow: 0 0 0 units($theme-input-select-border-width) color("base");
line-height: units($theme-input-select-size);
margin-right: units($input-select-margin-right);
text-indent: 0;
}

.usa-checkbox__input:checked + .usa-checkbox__label::before,
.usa-radio__input:checked + .usa-radio__label::before {
background-color: color("primary");
box-shadow: 0 0 0 units($theme-input-select-border-width) color("primary");
}

.usa-radio__input:checked + .usa-radio__label::before {
box-shadow: 0 0 0 units($theme-input-select-border-width) color("primary"),
inset 0 0 0 units($theme-input-select-border-width) color("white");

@media print {
box-shadow: inset 0 0 0 units($theme-input-select-border-width)
color("white"),
inset 0 0 0 units(2) color("primary"),
0 0 0 units($theme-input-select-border-width) color("primary");
}
}

.usa-checkbox__input:checked + .usa-checkbox__label::before,
.usa-checkbox__input:checked:disabled + .usa-checkbox__label::before {
@include add-background-svg("correct8");
background-position: center center;
background-size: units(1.5) auto;

@media print {
background-image: none;
background-color: color("white");
content: url("#{$theme-image-path}/checkbox-check-print.svg");
text-indent: 0;
}
}

.usa-radio__input:focus + .usa-radio__label::before {
@include focus-outline(null, null, null, 0.5);
}

.usa-checkbox__input:disabled + .usa-checkbox__label,
.usa-radio__input:disabled + .usa-radio__label {
color: color("disabled");
cursor: not-allowed;
}

.usa-checkbox__input:focus + .usa-checkbox__label::before {
@include focus-outline;
}

.usa-checkbox__input:disabled + .usa-checkbox__label::before,
.usa-radio__input:disabled + .usa-radio__label::before {
background: color("disabled-light");
box-shadow: 0 0 0 units($theme-input-select-border-width) color("disabled");
cursor: not-allowed;
}

.usa-radio__input:checked:disabled + .usa-radio__label::before {
background: color("disabled-dark");
box-shadow: 0 0 0 2px color("disabled-dark"),
inset 0 0 0 2px color("disabled-light");
}

// Checkboxes and radios with tap-friendly targets
.usa-checkbox__input--tile + .usa-checkbox__label,
.usa-radio__input--tile + .usa-radio__label {
border: units($theme-input-tile-border-width) solid
color($theme-input-tile-border-color);
border-radius: radius($theme-input-tile-border-radius);
margin-top: units(1);
padding: units(1.5) units(2) units(1.5) units(5);
}

.usa-checkbox__input--tile:checked + .usa-checkbox__label,
.usa-radio__input--tile:checked + .usa-radio__label {
background-color: color($theme-input-tile-background-color-selected);
border-color: color($theme-input-tile-border-color-selected);
}

.usa-checkbox__input--tile:disabled:checked + .usa-checkbox__label,
.usa-radio__input--tile:disabled:checked + .usa-radio__label {
background-color: color("disabled-light");
border-color: color($theme-input-tile-border-color);
}

.usa-checkbox__label-description,
.usa-radio__label-description {
display: block;
font-size: size("ui", "2xs");
margin-top: units(1);
text-indent: 0;
}

// Test code for scoped custom colors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test code is used to power the example here: https://federalist-3b6ba08e-0df4-44c9-ac73-6fc193b0e19c.app.cloud.gov/preview/uswds/uswds/jm-tile-add-bg/components/preview/checkbox--test.html

We should comment it out before going into production

.checkbox-tests {
@include set-text-and-bg("green-80");
@include checkbox-and-radio-colors("green-80", "green-warm-10v");
padding: units(2);
border-radius: radius("md");
}