No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    Full solution to Dynamic color scheme + extras

    Help
    6
    19
    6228
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • mesqueeb
      mesqueeb last edited by mesqueeb

      The following two SCSS mixins I need to use in Quasar Framework in Stylus:

      • Responsive Typography with min/max font-sizes:
        https://www.sassmeister.com/gist/7f22e44ace49b5124eec

      • Dynamic Theme CSS generator for multiple theme variables:
        https://www.sassmeister.com/gist/e99b7a8c01ef87d0dff8

      Once I found out how to rewrite these in Stylus I’ll post here so it can be useful for others as well!

      1 Reply Last reply Reply Quote 2
      • L
        leopiccionia last edited by

        @mesqueeb First mixin:

        strip-unit($value)
          unit($value, '')
        
        fluid-type($properties, $min-vw, $max-vw, $min-value, $max-value)
          for $property in $properties
            {$property}: $min-value
        
          @media screen and (min-width: $min-vw)
            for $property in $properties
              {$property}: s('calc(%s + %s * (100vw - %s) / %s)', $min-value, strip-unit($max-value - $min-value), $min-vw, strip-unit($max-vw - $min-vw))
        
          @media screen and (min-width: $max-vw)
            for $property in $properties
              {$property}: $max-value
        
        /* Single property */
        html
          fluid-type(font-size, 320px, 1366px, 14px, 18px)
        
        /* Multiple properties with same values */
        h1
          fluid-type(padding-bottom padding-top, 20em, 70em, 2em, 4em)
        
        1 Reply Last reply Reply Quote 3
        • mesqueeb
          mesqueeb last edited by

          @leopiccionia WOW!!! Thanks so much!!

          1 Reply Last reply Reply Quote 0
          • L
            leopiccionia last edited by leopiccionia

            @mesqueeb The following is functionally equivalent to second mixin, if I understood it correctly. If you’re curious, @(...){...} defines an anonymous mixin (much like an anonymous function). The second parameter can be either a named mixin or, in the following case, an anonymous mixin:

            $themes = {
              "theme-1": {
                "color": red
              },
              "theme-2": {
                "color": orange
              },
              "theme-3": {
                "color": yellow
              },
              "theme-4": {
                "color": green
              },
              "theme-5": {
                "color": blue
              }
            }
            
            themify($themes, $mixin)
              for $theme in $themes
                .{$theme} &
                  $mixin($themes[$theme])
            
            .test
              themify($themes, @($theme) {
                color: $theme.color
              })
            
            1 Reply Last reply Reply Quote 2
            • L
              leopiccionia last edited by

              Uhm, I don’t know why the Stylus code is not being syntax-highlighted.

              1 Reply Last reply Reply Quote 0
              • L
                leopiccionia last edited by leopiccionia

                This post is deleted!
                1 Reply Last reply Reply Quote 0
                • mesqueeb
                  mesqueeb last edited by

                  Wow. @leopiccionia you are a Stylus pro!!! You have just solved so many people’s problems trying to have dynamic theming!

                  1 Reply Last reply Reply Quote 1
                  • L
                    leopiccionia last edited by

                    Although I prefer Stylus, I’m actually more used to SCSS (which I use on my job). I used the Stylus compiler (a NPM package!) and trial-and-error approach. Some features, like anonymous and high-order functions/mixins, were actually great surprises, as I haven’t used them before in Stylus.

                    1 Reply Last reply Reply Quote 0
                    • mesqueeb
                      mesqueeb last edited by mesqueeb

                      @leopiccionia I was able to successfully integrate it into my stylus files.

                      The very cool thing you can do with this. You know Quasar has a lot of components where you can e.g. color="primary.
                      Now if I include a styl file like so:

                      .text-primary
                        themify($themes, @($theme) {
                          color: $theme.$primary !important
                        })
                      .bg-primary
                        themify($themes, @($theme) {
                          background: $theme.$primary !important
                        })
                      

                      And you have a primary color setup for another theme e.g. theme-retro. Then just by adding the class theme-retro to the body tag all component’s primary color will change into your new theme!
                      Isn’t that cool? : )

                      You’d need to setup the retro theme like so:

                      $themes = {
                        "theme-retro": {
                          "$primary": purple
                        },
                      }
                      

                      Now the final question: Do you think it’s possible to wrap it into another mixin to make using the mixin less verbose?
                      Cheers!

                      1 Reply Last reply Reply Quote 2
                      • mesqueeb
                        mesqueeb last edited by mesqueeb

                        Full example:

                        The variables in a styl file:

                        $themes = {
                          "theme-default": {
                            '$primary': $primary
                            '$secondary': $secondary
                            '$tertiary': $tertiary
                        
                            '$neutral': $neutral
                            '$positive': $positive
                            '$negative': $negative
                            '$info': $info
                            '$warning': $warning
                        
                            '$light': $light
                            '$dark': $dark
                          },
                          "theme-retro": {
                            '$primary': purple
                            '$secondary': lime
                            '$tertiary': grey
                        
                            '$neutral': $neutral
                            '$positive': $positive
                            '$negative': $negative
                            '$info': $info
                            '$warning': $warning
                        
                            '$light': $dark
                            '$dark': $light
                          },
                        }
                        // Create the Stylus mixin:
                        themify($themes, $mixin)
                          for $theme in $themes
                            .{$theme} &
                              $mixin($themes[$theme])
                        

                        You can see that the themes hold the original values from Quasar. To change these you best change them before you make your $themes object.
                        Then in the theme-retro you see I can leave original options or change to my second theme. I can even switch around light and dark!

                        Then you have to add all the Quasar color classes with the correct mixin like so:

                        
                        .text-primary
                          themify($themes, @($theme) {
                            color: $theme.$primary !important
                          })
                        
                        .bg-primary
                          themify($themes, @($theme) {
                            background: $theme.$primary !important
                          })
                        
                        .text-secondary
                          themify($themes, @($theme) {
                            color: $theme.$secondary !important
                          })
                        .bg-secondary
                          themify($themes, @($theme) {
                            background: $theme.$secondary !important
                          })
                        
                        .text-tertiary
                          themify($themes, @($theme) {
                            color: $theme.$tertiary !important
                          })
                        .bg-tertiary
                          themify($themes, @($theme) {
                            background: $theme.$tertiary !important
                          })
                        
                        .text-faded
                          themify($themes, @($theme) {
                            color: $theme.$faded !important
                          })
                        .bg-faded
                          themify($themes, @($theme) {
                            background: $theme.$faded !important
                          })
                        
                        .text-positive
                          themify($themes, @($theme) {
                            color: $theme.$positive !important
                          })
                        .bg-positive
                          themify($themes, @($theme) {
                            background: $theme.$positive !important
                          })
                        
                        .text-negative
                          themify($themes, @($theme) {
                            color: $theme.$negative !important
                          })
                        .bg-negative
                          themify($themes, @($theme) {
                            background: $theme.$negative !important
                          })
                        
                        .text-info
                          themify($themes, @($theme) {
                            color: $theme.$info !important
                          })
                        .bg-info
                          themify($themes, @($theme) {
                            background: $theme.$info !important
                          })
                        
                        .text-warning
                          themify($themes, @($theme) {
                            color: $theme.$warning !important
                          })
                        .bg-warning
                          themify($themes, @($theme) {
                            background: $theme.$warning !important
                          })
                        
                        .text-light
                          themify($themes, @($theme) {
                            color: $theme.$light !important
                          })
                        .bg-light
                          themify($themes, @($theme) {
                            background: $theme.$light !important
                          })
                        
                        .text-dark
                          themify($themes, @($theme) {
                            color: $theme.$dark !important
                          })
                        .bg-dark
                          themify($themes, @($theme) {
                            background: $theme.$dark !important
                          })
                        

                        That’s all! Now your Quasar components will change when you change a class on the <body> tag from theme-default to theme-retro.

                        1 Reply Last reply Reply Quote 2
                        • L
                          leopiccionia last edited by

                          @mesqueeb You could obviously wrap themify inside another mixin, but I don’t think it’s a scalable solution, as you’d need to know the keys ($primary, $secondary) a priori, and maintain a value to each key in each theme.

                          I’d rather pass a mixin to themify that infer the color keys from the theme itself.

                          themify-palette($theme)
                            for $k, $v in $theme
                              $k-stripped = match('^\$(.*)', $k)[1]
                              & .bg-{$k-stripped}
                                background-color: $v !important
                              & .text-{$k-stripped}
                                color: $v !important
                          
                          themify($themes, themify-palette)
                          

                          As a side note, I’d say something like this is more readable:

                          $themes = {
                            'theme-default': {
                              'colors': {
                                'primary': $primary
                                'secondary': $secondary
                                'tertiary': $tertiary
                          
                                'neutral': $neutral
                                'positive': $positive
                                'negative': $negative
                                'info': $info
                                'warning': $warning
                          
                                'light': $light
                                'dark': $dark
                              },
                            },
                            'theme-retro': {
                              'colors': {
                                'primary': purple
                                'secondary': lime
                                'tertiary': grey
                          
                                'neutral': $neutral
                                'positive': $positive
                                'negative': $negative
                                'info': $info
                                'warning': $warning
                          
                                'light': $dark
                                'dark': $light
                              },
                            },
                          }
                          
                          themify($themes, $mixin)
                            for $theme in $themes
                              .{$theme} &
                                $mixin($themes[$theme])
                          
                          themify-palette($theme)
                            for $k, $v in $theme.colors
                              & .bg-{$k}
                                background-color: $v !important
                              & .text-{$k}
                                color: $v !important
                          
                          themify($themes, themify-palette)
                          
                          1 Reply Last reply Reply Quote 0
                          • rstoenescu
                            rstoenescu Admin last edited by

                            Dynamic branding colors - configurable at any time during runtime in 0.15.7 already – to be released in less than 24 hours.

                            V 1 Reply Last reply Reply Quote 2
                            • mesqueeb
                              mesqueeb last edited by

                              @rstoenescu Did I inspire you to add this?! : D
                              Can’t wait!!

                              1 Reply Last reply Reply Quote 0
                              • mesqueeb
                                mesqueeb last edited by

                                @leopiccionia
                                The first mixin with the fluid font-size etc. Is it possible that it doesn’t work well with setting some height to vh?

                                .o-hero-carousel
                                  fluid-type(height, $breakpoint-xs, $breakpoint-lg, 50vh, 80vh)
                                

                                I tried this but the calculation seems to be a little bit off. Can I use anything besides px? (what about rem and em?)

                                L 1 Reply Last reply Reply Quote 0
                                • L
                                  leopiccionia @mesqueeb last edited by

                                  @mesqueeb

                                  The first mixin with the fluid font-size etc. Is it possible that it doesn’t work well with setting some height to vh?

                                  Your problem may be related to an issue where some browsers doesn’t allow vh and vw values inside calc() expressions.

                                  (what about rem and em?)

                                  It should work as expected, as my mixin and the one you provided in Sass should output the same on a demo using em. If the outputs are different, let me know.

                                  1 Reply Last reply Reply Quote 0
                                  • rstoenescu
                                    rstoenescu Admin last edited by

                                    Are you guys aware of https://quasar-framework.org/components/color-palette.html#Dynamic-Change-of-Brand-Colors-Dynamic-Theme-Colors ?

                                    1 Reply Last reply Reply Quote 3
                                    • V
                                      vigneshsivaraj @rstoenescu last edited by

                                      @rstoenescu how to dynamically change the theme of an app
                                      according to user ?any tutorial please suggest

                                      1 Reply Last reply Reply Quote 0
                                      • C
                                        CodeGrue last edited by CodeGrue

                                        I created the following Vuex module to switch between a Light and Dark theme.

                                        import { colors } from "quasar";
                                        
                                        const themes = {
                                          namespaced: true,
                                          state: { name: "Light" },
                                          mutations: {
                                            SET_THEME(state, newTheme) {
                                              state.name = newTheme.name;
                                              colors.setBrand("primary", newTheme.primary);
                                              colors.setBrand("secondary", newTheme.secondary);
                                              colors.setBrand("accent", newTheme.accent);
                                            }
                                          },
                                          actions: {
                                            ChangeTheme(context) {
                                              if (context.state.name == "Dark") {
                                                context.commit("SET_THEME", lightTheme);
                                              } else {
                                                context.commit("SET_THEME", darkTheme);
                                              }
                                            }
                                          }
                                        };
                                        
                                        const darkTheme = {
                                          name: "Dark",
                                          primary: "#222222",
                                          secondary: "#111111",
                                          accent: "#333333"
                                        };
                                        
                                        const lightTheme = {
                                          name: "Light",
                                          primary: "#cce6ff",
                                          secondary: "#0052a3",
                                          accent: "#f57b00"
                                        };
                                        
                                        export default themes;
                                        

                                        Missing currently are some of the text colors which seem to be set through classes not a palette.

                                        Just call this to flip between the themes:

                                        this.$store.dispatch("themes/ChangeTheme");

                                        S 1 Reply Last reply Reply Quote 0
                                        • S
                                          ScoutKirkOlson @CodeGrue last edited by

                                          @CodeGrue said in Full solution to Dynamic color scheme + extras:

                                          import { colors } from “quasar”;

                                          Your VueX solution works for the Quasar stylus variables only, not for custom added variables does it?
                                          Is there way to dynamically change those as well?

                                          1 Reply Last reply Reply Quote 0
                                          • First post
                                            Last post