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

Switch component #3764

Open
stsrki opened this issue Apr 1, 2024 · 9 comments
Open

Switch component #3764

stsrki opened this issue Apr 1, 2024 · 9 comments

Comments

@stsrki
Copy link
Contributor

stsrki commented Apr 1, 2024

Hello. Is there a plan to work on the switch component?

image

@jgthms
Copy link
Owner

jgthms commented Apr 1, 2024

There is not. It's fairly standard to design but it would require JavaScript to work.

@stsrki
Copy link
Contributor Author

stsrki commented Apr 1, 2024

Not necessarily. It can be styled around the <input type="checkbox">. And by targeting the :checked, &:not(:checked) pseudo selectors.

@jgthms
Copy link
Owner

jgthms commented Apr 2, 2024

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.

@stsrki
Copy link
Contributor Author

stsrki commented Apr 2, 2024

Some other Bulma components require a bit of JavaScript so I'll think about it.

Appreciate it.

@jbrazeau
Copy link

jbrazeau commented Apr 2, 2024

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 through cv.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.

@digitigradeit
Copy link

@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

@jbrazeau
Copy link

jbrazeau commented Apr 3, 2024

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))

@digitigradeit
Copy link

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)...

@digitigradeit
Copy link

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 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants