bulma
bulma copied to clipboard
Switch component
Hello. Is there a plan to work on the switch component?
There is not. It's fairly standard to design but it would require JavaScript to work.
Not necessarily. It can be styled around the <input type="checkbox">
. And by targeting the :checked
, &:not(:checked)
pseudo selectors.
Yes but that's more of a hack.
Also, on mobile devices, you can drag that control. If you want to replicate that UX, you require Javascript.
Some other Bulma components require a bit of JavaScript so I'll think about it.
Some other Bulma components require a bit of JavaScript so I'll think about it.
Appreciate it.
I've created a patch for bulma-switch
by basically :
- switching from indented to sass syntax
- using sass for building process (instead of gulp)
- replacing
$color
variable usages by vars throughcv.getVar($name)
(because as far as I can see this allows to support bulma themes correctly instead if using direct colors) - adding a
sample.html
page to test the result (with a dark mode enabler)
The code is available here : https://gitlab.com/jf.brazeau/bulma-switch-migration
The changes are listed here : https://gitlab.com/jf.brazeau/bulma-switch-migration/-/commit/c3a2b3e2e61bfd1d420b73315aba78f963fd62fb
I think I will use the scss directly in my project until the extension is officially migrated.
@jgthms : congratulations for Bulma, really great framework.
@jbrazeau haha you beat me to it!
I was working on it as well. it's remarkable how similar the code is.. Mine loosely based on the /Wikiki/bulma-switch version.
with additional mixin support.
@use "sass:math";
@use "sass:list";
@use "../node_modules/bulma/sass/utilities/initial-variables" as iv;
@use "../node_modules/bulma/sass/utilities/derived-variables" as dv;
@use "../node_modules/bulma/sass/utilities/css-variables" as cv;
@use "../node_modules/bulma/sass/utilities/extends" as ext;
@use "../node_modules/bulma/sass/utilities/controls" as ctrl;
$switch-background: iv.$grey-light !default;
$switch-background-active: dv.$primary !default;
$switch-colors: dv.$colors !default;
$switch-outline-width: ctrl.$control-border-width !default;
$switch-margin: 1rem !default;
$switch-paddle-background: iv.$white !default;
$switch-paddle-background-active: iv.$white !default;
$switch-paddle-offset: 0.25rem !default;
$switch-paddle-transition-duration: cv.getVar("duration") !default;
$switch-paddle-transition-property: background-color, border-color, opacity, left !default;
$switch-paddle-transition-timing-function: cv.getVar("easing") !default;
$switch-paddle-transition: $switch-paddle-transition-property $switch-paddle-transition-duration $switch-paddle-transition-timing-function !default;
$switch-radius: iv.$radius !default;
@mixin switch-color($color-active: $switch-background-active, $color-inactive: $switch-background) {
&.is-outlined {
label {
background-color: transparent;
outline-style: solid;
outline-width: ctrl.$control-border-width;
outline-color: $color-inactive;
}
label::before {
background-color: $switch-paddle-background;
}
input:checked~label {
outline-color: $color-active;
background-color: transparent;
}
input:checked~label::before {
background-color: $color-active;
}
}
label {
background-color: $color-inactive;
}
input:checked~label {
background-color: $color-active;
&::before {
background-color: $switch-paddle-background-active;
}
}
}
// Mixin for switch size
@mixin switch-size($size: dv.$size-normal) {
$switch-height: $size * 2;
$switch-width: $switch-height * 2;
$paddle-height: $switch-height - ($switch-paddle-offset * 2);
$paddle-width: $switch-height - ($switch-paddle-offset * 2);
$paddle-active-offset: $switch-width - $paddle-width - $switch-paddle-offset;
input:checked~label::before {
left: $paddle-active-offset;
}
label {
position: relative;
display: block;
width: $switch-width;
height: $switch-height;
border-radius: $switch-radius;
&::before {
width: $paddle-width;
height: $paddle-height;
top: $switch-paddle-offset;
left: $switch-paddle-offset;
border-radius: $switch-radius;
background-color: $switch-paddle-background;
transition: $switch-paddle-transition;
}
&::after {
font-size: $size;
//height: $paddle-height;
margin-left: $switch-width + 1rem;
}
}
&.is-rounded {
label {
border-radius: math.div($switch-height, 2);
&::before {
border-radius: 50%;
}
}
}
}
.switch {
position: relative;
display: inline-block;
margin-bottom: $switch-margin;
outline: none;
user-select: none;
input {
display: none;
opacity: 0;
}
label {
opacity: 1;
display: flex;
align-items: center;
text-wrap: nowrap;
vertical-align: middle;
}
label::before,
label:before {
position: absolute;
content: '';
flex-grow: 0;
flex-shrink: 0;
display: flex;
}
label::after,
label:after {
position: absolute;
//flex-grow: 1;
//flex-shrink: 0;
display: flex;
align-items: center;
content: attr(data-label-off);
//width: 100%;
height: 100%;
}
input:checked~label::after {
content: attr(data-label-on);
}
@include switch-color;
@include switch-size;
}
@each $name, $color in $switch-colors {
$color-base: $color;
@if type-of($color =="list") {
$color-base: list.nth($color, 1);
}
.switch.is-#{$name} {
@include switch-color($color-base);
}
}
// Sizes
.switch {
@include switch-size(dv.$size-normal);
}
.switch.is-small {
@include switch-size(dv.$size-small);
}
.switch.is-normal {
@include switch-size(dv.$size-normal);
}
.switch.is-medium {
@include switch-size(dv.$size-medium);
}
.switch.is-large {
@include switch-size(dv.$size-large);
}
example usage:
<div class="control is-expanded">
<div class="switch is-outlined is-rounded">
<input id="exampleSwitch1" type="checkbox" name="exampleSwitch1">
<label for="exampleSwitch1" data-label-off="Normal switch off" data-label-on="Normal switch on"></label>
</div>
</div>
<div class="control is-expanded">
<div class="switch is-small is-info">
<input id="exampleSwitch2" type="checkbox" name="exampleSwitch2">
<label for="exampleSwitch2" data-label-off="Small switch off" data-label-on="Small switch on"></label>
</div>
</div>
I will try to incorporate as much of the :focus (etc) selectors I possibly can into it in the coming days.. Nice job though @jbrazeau
Hi @digitigradeit ! Thank for your reply ! In fact I didn't want to beat anybody 😉 I just need to migrate as soon as possible to bulma 1.0 so that I did need bulma-switch
to work quickly. But I'm sure your contribution will be more mature than mine, so I look forward to hearing from you and as soon as possible I'll switch to your version or any officially supported version of bulma-switch
(compliant with bulma 1.0).
Note : is using the colors directly like in the initial bulma-switch implementation compliant with the new theming feature of bulma ? I thought I needed to used CSS variables to fully support it. Am I wrong ? (the reason why I used cv.getVar($name)
)
if you look at buttons, tags, etc anything with color support it usually copies dv.$colors to a local variable i.e. $button-colors and then has a loop referencing that. the color loop is slightly different now with 1.0 however... although with the concept of themes, im not sure which is better. but I would also venture that the entire color loop in general for this component is overkill as most people probably dont have switch skittles scattered on their site, rather a color for on and color for offoff... that why I recreated the mixin I did but also gave it some flexibility (if needed). by default it is grey (off) and primary (on)...
slightly off-topic, i'm also working on a bulma-social (social buttons) for v1.0 too! that'd be a lot of fun and could use help with that as well :)
Hello @jbrazeau @digitigradeit, are you planning to release a npm package with an updated version of the switch?