Skip to content

Commit df27446

Browse files
feat(component): Add Switch component (#2924)
* feat(component): Add Switch component * After rebase * Final touch * doc: update migraion switch like radio and checkbox * doc: use partials from Radio component in doc * fix: augment bundlewatch ci limit * fix(review) --------- Co-authored-by: Maxime Lardenois <[email protected]>
1 parent 798edc6 commit df27446

24 files changed

+506
-54
lines changed

Diff for: .bundlewatch.config.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
"files": [
33
{
44
"path": "./dist/css/ouds-web-bootstrap.css",
5-
"maxSize": "64.0 kB"
5+
"maxSize": "64.75 kB"
66
},
77
{
88
"path": "./dist/css/ouds-web-bootstrap.min.css",
9-
"maxSize": "61.0 kB"
9+
"maxSize": "61.5 kB"
1010
},
1111
{
1212
"path": "./dist/css/ouds-web-grid.css",

Diff for: scss/_root.scss

-4
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,6 @@
431431
--#{$prefix}form-color-disabled-filter: #{$form-color-disabled-filter}; // OUDS mod
432432
--#{$prefix}form-select-indicator: #{$form-select-indicator}; // OUDS mod
433433
--#{$prefix}form-select-disabled-indicator: #{$form-select-disabled-indicator}; // OUDS mod
434-
--#{$prefix}form-switch-square-bg: #{$form-switch-square-bg}; // OUDS mod
435-
--#{$prefix}form-switch-unchecked-invalid-border-color: #{$form-switch-unchecked-invalid-border-color}; // OUDS mod
436434

437435
// OUDS mod
438436
// Table-specific styles
@@ -525,8 +523,6 @@
525523
--#{$prefix}form-select-indicator: #{$form-select-indicator-dark}; // OUDS mod
526524
--#{$prefix}form-select-disabled-indicator: #{$form-select-disabled-indicator-dark}; // OUDS mod
527525
--#{$prefix}form-color-disabled-filter: #{$form-color-disabled-filter-dark};
528-
--#{$prefix}form-switch-square-bg: #{$form-switch-square-bg-dark}; // OUDS mod
529-
--#{$prefix}form-switch-unchecked-invalid-border-color: #{$form-switch-unchecked-invalid-border-color-dark}; // OUDS mod
530526

531527
// OUDS mod
532528
// Table-specific styles

Diff for: scss/_variables-dark.scss

-2
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ $svg-as-custom-props-dark: (
9999
//
100100

101101
$form-color-disabled-filter-dark: brightness(0) invert(1) brightness(.4) !default; // OUDS mod
102-
$form-switch-square-bg-dark: $ouds-color-functional-dark-gray-880 !default; // OUDS mod
103102

104103
// OUDS mod: no $form-select-indicator-color-dark
105104
$form-select-indicator-dark: escape-svg(url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 7'><path fill='#{$white}' d='M7 7 0 0h14L7 7z'/></svg>")) !default; // OUDS mod: instead of Bootstrap svg
@@ -113,7 +112,6 @@ $form-valid-color-dark: $ouds-color-content-default-da
113112
$form-valid-border-color-dark: $ouds-color-border-emphasized-dark !default; // OUDS mod: instead of `$green-300`
114113
$form-invalid-color-dark: $ouds-color-action-negative-enabled-dark !default; // OUDS mod: instead of `$red-300`
115114
$form-invalid-border-color-dark: $ouds-color-action-negative-enabled-dark !default; // OUDS mod: instead of `$red-300`
116-
$form-switch-unchecked-invalid-border-color-dark: $form-invalid-border-color-dark !default; // OUDS mod
117115
// scss-docs-end form-validation-colors-dark
118116

119117
//

Diff for: scss/_variables.scss

+7-29
Original file line numberDiff line numberDiff line change
@@ -1104,43 +1104,21 @@ $form-star-rating-sm-unchecked-icon: escape-svg(url("data:image/svg+xml,<svg
11041104
// End mod
11051105
// scss-docs-end form-check-variables
11061106

1107-
// fusv-disable
11081107
// scss-docs-start form-switch-variables
11091108
// OUDS mod: no $form-switch-color
1110-
$form-switch-width: $spacer * 3 !default; // OUDS mod
1111-
$form-switch-padding-start: $form-switch-width + .625rem !default; // OUDS mod
1112-
$form-switch-bg-image: var(--#{$prefix}close-icon) !default; // OUDS mod
1113-
$form-switch-bg-position: right .5rem top 50% !default; // OUDS mod
1114-
$form-switch-bg-size: .75rem !default; // OUDS mod
1115-
$form-switch-bg-square-size: add(1rem, $spacer * .5) !default; // OUDS mod
1116-
$form-switch-border-radius: null !default; // OUDS mod
1117-
$form-switch-transition: background-position .15s ease-in-out, $transition-focus !default; // OUDS mod
1118-
1119-
$form-switch-square-bg: $black !default; // OUDS mod
1120-
$form-switch-bg: $white !default; // OUDS mod
1121-
$form-switch-border-color: $white !default; // OUDS mod
1122-
$form-switch-filter: var(--#{$prefix}form-check-filter) !default; // OUDS mod
1123-
$form-switch-focus-visible-inner: $black !default; // OUDS mod
1124-
$form-switch-focus-visible-outer: $white !default; // OUDS mod
1109+
// OUDS mod: no $form-switch-width
1110+
// OUDS mod: no $form-switch-padding-start
1111+
// OUDS mod: no $form-switch-bg-image
1112+
$form-switch-border-radius: $ouds-switch-border-radius !default; // OUDS mod: instead of `$form-switch-width`
1113+
$form-switch-transition: width .15s cubic-bezier(.2, 0, 0, 1), height .15s cubic-bezier(.2, 0, 0, 1), left .15s cubic-bezier(.2, 0, 0, 1) !default; // OUDS mod: instead of `background-position .15s ease-in-out`
11251114

11261115
// OUDS mod: no $form-switch-focus-color
11271116
// OUDS mod: no $form-switch-focus-bg-image
11281117

11291118
// OUDS mod: no $form-switch-checked-color
1130-
$form-switch-checked-bg-image: $form-check-input-checked-bg-image !default; // OUDS mod
1131-
$form-switch-checked-bg-size: add(map-get($spacers, 2), map-get($spacers, 1)) !default; // OUDS mod
1132-
// stylelint-disable-next-line function-disallowed-list
1133-
$form-switch-checked-bg-position: calc(var(--#{$prefix}border-width) * 3) 50% !default; // OUDS mod
1134-
1135-
$form-switch-checked-square-bg: var(--#{$prefix}body-bg) !default; // OUDS mod
1136-
$form-switch-checked-bg: $ouds-color-orange-500 !default; // OUDS mod
1137-
$form-switch-checked-border-color: $ouds-color-orange-500 !default; // OUDS mod
1138-
$form-switch-checked-filter: none !default; // OUDS mod
1139-
$form-switch-checked-focus-inner: var(--#{$prefix}color-border-focus-inset) !default; // OUDS mod
1140-
$form-switch-checked-focus-outer: var(--#{$prefix}color-border-focus) !default; // OUDS mod
1141-
$form-switch-unchecked-invalid-border-color: #31c3eb !default; // OUDS mod: will be rendered red when mixed with the filter
1119+
$form-switch-checked-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='#000' d='m17.413 8.962-6.207 7.2a.998.998 0 0 1-.758.338.997.997 0 0 1-.757-.338l-3.103-3.6A.857.857 0 0 1 6.375 12c0-.248.109-.473.284-.636l.388-.36c.175-.163.418-.264.686-.264.24 0 .461.082.63.217l1.891 1.943 5.738-5.157c.173-.15.407-.243.663-.243.536 0 .97.403.97.9 0 .213-.08.408-.212.562Z'/></svg>") !default; // OUDS mod: instead of Bootstrap icon
1120+
// OUDS mod: no $form-switch-checked-bg-position
11421121
// scss-docs-end form-switch-variables
1143-
// fusv-enable
11441122

11451123
// scss-docs-start input-group-variables
11461124
$input-group-addon-padding-y: $input-padding-y !default;

Diff for: scss/forms/_control-item.scss

+114
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,107 @@
280280
}
281281

282282

283+
//
284+
// Control item switch indicator
285+
//
286+
287+
@keyframes switch-check-in {
288+
0%,
289+
99% {
290+
background-color: transparent;
291+
}
292+
100% {
293+
background-color: $ouds-switch-color-check;
294+
}
295+
}
296+
297+
.control-item-indicator[role="switch"] {
298+
min-width: $ouds-switch-size-min-width;
299+
min-height: $ouds-switch-size-min-height;
300+
background-color: $ouds-switch-color-track-unselected;
301+
border: 0;
302+
@include border-radius($ouds-switch-border-radius, $ouds-switch-border-radius);
303+
304+
&[type="checkbox"]::before {
305+
position: absolute;
306+
top: 50%;
307+
left: $ouds-switch-space-padding-inline-unselected;
308+
display: block;
309+
width: $ouds-switch-size-width-cursor-unselected;
310+
height: $ouds-switch-size-height-cursor-unselected;
311+
content: "";
312+
background-color: $ouds-switch-color-cursor;
313+
box-shadow: $ouds-elevation-raised;
314+
mask: none;
315+
transform: translateY(-50%);
316+
@include border-radius($form-switch-border-radius, $form-switch-border-radius);
317+
@include transition($form-switch-transition);
318+
}
319+
320+
&:hover,
321+
&:focus-visible,
322+
&:active {
323+
background-color: $ouds-switch-color-track-unselected-interaction;
324+
}
325+
326+
&:active::before {
327+
width: $ouds-switch-size-width-cursor-unselected-pressed;
328+
}
329+
330+
&:disabled {
331+
background-color: $ouds-color-action-disabled;
332+
}
333+
334+
&:checked {
335+
background-color: $ouds-switch-color-track-selected;
336+
337+
&::before {
338+
left: calc($ouds-switch-size-min-width - $ouds-switch-space-padding-inline-selected - $ouds-switch-size-width-cursor-selected); // stylelint-disable-line function-disallowed-list
339+
width: $ouds-switch-size-width-cursor-selected;
340+
height: $ouds-switch-size-height-cursor-selected;
341+
}
342+
343+
&:not(:active)::after {
344+
position: absolute;
345+
top: 50%;
346+
right: $ouds-switch-space-padding-inline-selected;
347+
display: block;
348+
width: $ouds-switch-size-width-cursor-selected;
349+
height: $ouds-switch-size-height-cursor-selected;
350+
content: "";
351+
background-color: $ouds-switch-color-check;
352+
opacity: $ouds-switch-opacity-check;
353+
mask: escape-svg($form-switch-checked-bg-image);
354+
transform: translateY(-50%);
355+
animation: .15s linear 0s switch-check-in;
356+
357+
@media (prefers-reduced-motion: reduce) {
358+
animation: none;
359+
}
360+
}
361+
362+
&:hover,
363+
&:focus-visible,
364+
&:active {
365+
background-color: $ouds-switch-color-track-selected-interaction;
366+
}
367+
368+
&:active::before {
369+
left: calc($ouds-switch-size-min-width - $ouds-switch-space-padding-inline-selected - $ouds-switch-size-width-cursor-selected-pressed); // stylelint-disable-line function-disallowed-list
370+
width: $ouds-switch-size-width-cursor-selected-pressed;
371+
}
372+
373+
&:disabled {
374+
background-color: $ouds-color-action-disabled;
375+
376+
&::after {
377+
background-color: $ouds-color-action-disabled;
378+
}
379+
}
380+
}
381+
}
382+
383+
283384
//
284385
// Control item standalone
285386
//
@@ -405,6 +506,19 @@
405506
}
406507

407508

509+
//
510+
// Switch
511+
//
512+
513+
.switch-item {
514+
@extend %control-item;
515+
}
516+
517+
.switch-standalone {
518+
@extend %control-item-standalone;
519+
}
520+
521+
408522
//
409523
// Bootstrap compatibility
410524
//

Diff for: scss/ouds-web-grid.scss

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ $include-column-box-sizing: true !default;
99
@import "tokens/semantic";
1010
@import "tokens/semantic-colors-custom-props";
1111
@import "tokens/composite";
12+
@import "tokens/component-colors-custom-props";
1213
@import "tokens/component";
1314
@import "variables";
1415
@import "variables-dark";

Diff for: scss/ouds-web-reboot.scss

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
@import "tokens/semantic";
88
@import "tokens/semantic-colors-custom-props";
99
@import "tokens/composite";
10+
@import "tokens/component-colors-custom-props";
1011
@import "tokens/component";
1112
@import "variables";
1213
@import "variables-dark";

Diff for: scss/ouds-web-utilities.scss

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
@import "tokens/semantic";
99
@import "tokens/semantic-colors-custom-props";
1010
@import "tokens/composite";
11+
@import "tokens/component-colors-custom-props";
1112
@import "tokens/component";
1213
@import "variables";
1314
@import "variables-dark";

Diff for: scss/ouds-web.scss

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
@import "tokens/semantic";
1010
@import "tokens/semantic-colors-custom-props";
1111
@import "tokens/composite";
12+
@import "tokens/component-colors-custom-props";
1213
@import "tokens/component";
1314
@import "variables";
1415
@import "variables-dark";

Diff for: site/assets/js/tac.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@
8686
'tarteaucitron.userInterface.respond(document.getElementById(\'googletagmanagerAllowed\'),document.getElementById(\'googletagmanagerAllowed\').checked);'
8787
const toggle = document
8888
.createRange()
89-
.createContextualFragment( // TODO replace with a form-switch
90-
`<label class="checkbox-standalone ">
91-
<input class="control-item-indicator" type="checkbox" value="" id="googletagmanagerAllowed" aria-labelledby="googletagmanagerLine" onchange="${choiceEvent}"${((document.cookie.match(/^(?:.*;)?\s*cookie-consent\s*=\s*([^;]+)(?:.*)?$/) || [null])[1].match('!googletagmanager=true') ? 'checked' : '')}>
89+
.createContextualFragment(
90+
`<label class="switch-standalone">
91+
<input class="control-item-indicator" type="checkbox" role="switch" value="" id="googletagmanagerAllowed" aria-labelledby="googletagmanagerLine" onchange="${choiceEvent}"${((document.cookie.match(/^(?:.*;)?\s*cookie-consent\s*=\s*([^;]+)(?:.*)?$/) || [null])[1].match('!googletagmanager=true') ? 'checked' : '')}>
9292
<span class="visually-hidden">Google Tag Manager</span>
9393
<input id="googletagmanagerDenied" class="d-none">
9494
</label>`

Diff for: site/assets/scss/_tarteaucitron.scss

+4-4
Original file line numberDiff line numberDiff line change
@@ -162,18 +162,18 @@
162162
}
163163

164164
@include tac("Allow", true) {
165-
@include button-icon($form-switch-checked-bg-image, 1em);
165+
@include button-icon(escape-svg($form-check-input-checked-bg-image), 1.625em);
166166

167167
&::before {
168-
margin-right: $spacer / 2;
168+
margin-right: $spacer * .625;
169169
}
170170
}
171171

172172
@include tac("Deny", true) {
173-
@include button-icon($form-switch-bg-image, 1em);
173+
@include button-icon(escape-svg($cross-icon-stroke), 1em);
174174

175175
&::before {
176-
margin-right: $spacer / 2;
176+
margin-right: $spacer * .875;
177177
}
178178
}
179179

Diff for: site/assets/scss/docs.scss

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ $enable-rounded: true;
3333
@import "../../../scss/tokens/semantic";
3434
@import "../../../scss/tokens/semantic-colors-custom-props";
3535
@import "../../../scss/tokens/composite";
36+
@import "../../../scss/tokens/component-colors-custom-props";
3637
@import "../../../scss/tokens/component";
3738
@import "../../../scss/variables";
3839
@import "../../../scss/maps";

Diff for: site/assets/scss/search.scss

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
@import "../../../scss/tokens/semantic";
1212
@import "../../../scss/tokens/semantic-colors-custom-props";
1313
@import "../../../scss/tokens/composite";
14+
@import "../../../scss/tokens/component-colors-custom-props";
1415
@import "../../../scss/tokens/component";
1516
@import "../../../scss/variables";
1617
@import "../../../scss/mixins";

Diff for: site/content/docs/0.3/customize/color-palette.md

+1
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ Here's an example that generates text color utilities (e.g., `.text-purple-500`)
205205
@import "@ouds/web/scss/tokens/semantic";
206206
@import "@ouds/web/scss/tokens/semantic-colors-custom-props";
207207
@import "@ouds/web/scss/tokens/composite";
208+
@import "@ouds/web/scss/tokens/component-colors-custom-props";
208209
@import "@ouds/web/scss/tokens/component";
209210
@import "@ouds/web/scss/variables";
210211
@import "@ouds/web/scss/variables-dark";

Diff for: site/content/docs/0.3/forms/checkbox.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ You can find here the [OUDS Checkbox design guidelines](https://unified-design-s
6161

6262
## Approach
6363

64-
Browser default checkboxes are replaced with the help of `.checkbox-item`. Checkboxes are for selecting one or several options in a list.
64+
Browser default checkboxes are replaced with the help of `.control-item-indicator[type="checkbox"]`. Checkboxes are for selecting one or several options in a list.
6565

6666
Checkboxes are implemented using `.control-item-*` classes, see below.
6767

Diff for: site/content/docs/0.3/forms/radio-button.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ You can find here the [OUDS Radio button design guidelines](https://unified-desi
6060

6161
## Approach
6262

63-
Browser default radio buttons are replaced with the help of `.radio-button-item`. Radio buttons allows user to select a single option from a set of mutually exclusive choices.
63+
Browser default radio buttons are replaced with the help of `.control-item-indicator[type="radio"]`. Radio buttons allows user to select a single option from a set of mutually exclusive choices.
6464

6565
Radio buttons are implemented using `.control-item-*` classes, see below.
6666

@@ -368,4 +368,4 @@ Be careful using this, you must implement the background on hover, focus and act
368368
<input class="form-check-input" type="radio" id="radioNoLabel" value="" aria-label="...">
369369
</div>
370370
{{< /example >}}
371-
{{< /bootstrap-compatibility >}}
371+
{{< /bootstrap-compatibility >}}

0 commit comments

Comments
 (0)