Angular material change theme

Angular material change theme DEFAULT

Switch themes in angular material 5

Here's an alternative solution for Angular 5.1+/Angular Material 5.0+.

*Edit: As noted, this still works in Angular 7+.

Working editable example - https://stackblitz.com/edit/dynamic-material-theming

In theme.scss, include a default theme(notice it isn't kept under a class name - this is so Angular will use it as the default), and then a light and dark theme.

theme.scss

In the app.component file, include OverlayContainer from @angular/cdk/overlay. You can find Angular's documentation for this here https://material.angular.io/guide/theming; though their implementation is a little different. Please note, I also had to include OverlayModule as an import in app.module as well.

In my app.component file, I also declared as a variable, which will be used to set the theme as a class.

app.component.ts

app.module.ts

Finally, call the onSetTheme function from your view.

app.component.html

You might consider using an observable so that the functionality would be more dynamic.

Sours: https://stackoverflow.com/questions/47441036/switch-themes-in-angular-material-5

Let's implement a Theme Switch like the Angular Material Site

This article is mainly intended for beginners. I've added a TL;DR; below as a precautionary measure, in case you're a more advanced Angular Developer. Please feel free to navigate to a section that is most interesting to you.

TL;DR;

Link to this section

Why a Theme Switch?

Link to this section

Alright! So Dark Mode is a not so new cool feature. Most of the websites out there are implementing it as custom themes in their Apps.

And why wouldn't they do that, right? Dark Mode is awesome! It's easier on the eyes, better in terms of power consumption, and can provide an excellent user experience(especially in low-lighting conditions)

Yeah! You heard me. Low-lit ambiances are the best suited for Dark Mode. I mean, nobody's stopping you from changing to Dark Mode even in well-lit environments. But still, Dark Mode is easier on the eyes and makes more sense IN THE DARK.(see what I did there?)

Also, I mentioned Dark Mode as a way to enhance UX right? Well, there are multiple aspects to it. It's always better to offer users a way to customize the look and feel of your Apps, without compromising with your design language. And most of the Web Apps(or Apps, in general), do that via themes.

The other aspect might look more or less like a gimmick to some of you. But you can take the UX of your Web App, to the next level, by intelligently switching themes, based on the ambient lighting conditions that the user is in. I'll get back to this later.

One of my favorite websites, that implement Themes is the Angular Material Site. You might have seen this switch that lets you change the theme on the website.

Theme Switch on material.angular.io

We'll pretty much replicate the same effect in our Angular App. So without further ado, let's get started.

The Setup

Link to this section

I've set-up Angular Material on StackBlitz that you can use as a starter template:

From here on, let's add a few Angular Material Components that we can use to see something on the UI. I'll add a toolbar, an icon on it, a menu for theme options, and a button.

Since all these Angular Material Components will be used in my , it would make sense to create a separate that re-exports all the Material related modules from it.

<>Copy

And now I can add the to the array of my .

<>Copy

I'm doing this in here because I will be using all the Angular Material Components exposed by these Angular Material Modules in my . This would not make much sense in a Real-World Application as we would generally not use all the Angular Material Components in all our Modules. So creating a single and then importing it in every Angular Module that you create can lead to performance hits. So you might want to avoid that in such cases.

Moving on, I should now be able to use these Angular Material Components in my App. The look that I'm going for is really simple. THIS

The Sample App UI

Judging from the image above, we need a , a that opens upon clicking the ? icon and the rest would already be accommodated by our Sample StackBlitz.

I plan to make this a smart component. You can learn more about the Smart and Dumb Component Pattern from this video by Stephen Fluin.

Alright, now continuing with our , it needs to pass on some options for the menu to the . Each option would have things like, , , & for the icon to show on each menu item; and a , and a corresponding to each label.

Now we do know that Angular Material has 4 such pre-built themes named:

    So we'll need 4 items for options. To avoid hard-coding of these options in the component itself, I'll just expose this data as a json file and store it in the folder in a file named . Doing that will allow me to fetch it with path

    This file would look something like this:

    <>Copy

    Considering that this data was exposed as a REST API, I can then fetch it using in my App. And that's what I'll be doing in this article. Alternatively, you can also leverage it as a static asset instead of exposing this data via a REST API. If you do that, you can import it directly in the using . You'll just have to set , and to in the , in your /. I have an implementation for this version in this sample StackBlitz just in case you're interested.

    Okay. Let's carry on. Now, since I also have the structure of the Object, I can create an for static typing. Let's store it in a file named :

    <>Copy

    Perfect! Now the responsibility of the is to:

    • Render the header(Obviously!)
    • Fetch the options and give it to the .

    But we do need to also change the theme at some point. So it's better that we abstract the whole business logic related to themes in a service that I'd call . So let's implement that first:

    <>Copy

    Sweet! We can now inject this service as a dependency in the which would look something like this:

    <>Copy

    As you can see, the is also responsible for changing the theme now.

    And the template would look like this:

    <>Copy

    Notice how instead of ing to the in the Component Class, we've used the pipe to unwrap it. This is a pattern that makes Angular reactive and as far as possible, you should follow this pattern. Once we get the options, we can then pass it as an input to the 's property.

    Also, since the responsibility of changing the theme is also taken up by the , we can implement the as a dumb/presentational component. So let's do that now.

    So now we can tell that the would accept as an and then iterate through them to render these options. We can also clearly see that it has a property that calls the handler with the newly selected theme. So we can implement the Class like this:

    <>Copy

    And the template would look something like this:

    <>Copy

    Alright! Now we have everything in place. We just need a way to switch themes. How do we do that?

    Implementing the Theme Switch

    Link to this section

    This is the final piece of the puzzle. And we can do this in several different ways. But the Angular Material Website has already implemented this right? And the good thing is, it's open-source. So we do have access to the source code.

    So instead of trying to re-invent the wheel, I'm going to cheat a little bit and see how Angular Material Docs App did it.

    How Angular Material Website does it?

    Link to this section

    If you check the actual implementation, they have implemented something called a . This is what we see at the top-right, in the header.

    Theme Picker on material.angular.io

    This(as the name suggests) is responsible for switching the theme on the website. This component calls a service called .

    What does this service do, you might ask. Well, when you change the theme from the it:

    • Checks whether there's a link tag on the HTML Document with a attribute, the value of which is: :
    • If there isn't such a tag, it adds this tag to the head of the document, and then set the property with the selected theme path on it.
    • If there is such a tag, it then, it simply sets the property on this tag to the selected theme path.

    Great, now that we understand what the does, I can just copy the service in my project. Once I do that, I can just inject this in my and call the method from it with the appropriate values and it should ideally work.

    So let's try it out.

    Our Implementation

    Link to this section

    I'll first copy the in a file named :

    <>Copy

    Great. So now that I have this service in place, as planned, I'll inject this service as a dependency in my and implement the method:

    <>Copy

    All I'm doing here is calling the method from the with the name of the style key(theme in this case), and the value of the attribute that it has to set.

    The method, again, either creates a new tag and then sets the attribute on it; or updates the attribute on a pre-existing tag.

    And that's pretty much it. This is what our final code looks like.

    Perfect! We now have a theme switch, just like the one on the Angular Material Website. And it works as expected.

    Next Steps

    Link to this section

    This is all great. But wouldn't it be awesome if our App could automatically switch themes based on the ambient light? Well, that's exactly what we're going to do in the next article. Check it out here.


    I’m grateful to Martina Kraus, and Rajat Badjatya for taking the time to proofread it and providing all the constructive feedback in making this article better. I hope this article has taught you something new related to Angular. If it did share this article with your friends who are new to Angular and want to achieve something similar.

    This article was originally published by me under the Angular Publication on DEV.TO
    Sours: https://indepth.dev/posts/1218/lets-implement-a-theme-switch-like-the-angular-material-site
    1. Juice wrld electrax
    2. 5960x overclocked
    3. Japanese room dividers
    4. Beats studio wireless charger port

    Custom themes with Angular Material

    When building bigger applications, we always strive for flexibility, extensibility and reusability. This applies not only to the actual application logic, but also to style sheets. Especially nowadays, where things like CSS variables and modules exist. These tools are great and they solve many different problems in a very elegant way. However, one thing that’s still super hard to do these days is theming. Being able to use existing, or create new components, but easily changing their look and feel without changing their code. This is often required when we build things that can be reused across different projects, or if the project we’re working on should simply enable the user to change the color scheme.

    The Angular Material project comes with a built-in story for theming, including using any of Material Design’s own predefined themes, but also creating custom themes that will be used not only by components provided by Angular Material, but also our own custom ones.

    In this article we’ll explore how theming is implemented, how pre-built themes can be used and how we can make our own custom components theme-able so they pick up the configured theme as well!

    What is a theme?

    “Theme” can mean many different things to different people, so it’s good to clarify what a theme in the context of Angular Material means. Let’s get right into it.

    The official theming guide is pretty much to the point here:

    A theme is a set of colors that will be applied to the Angular Material components.

    To be more specific, a theme is a composition of color palettes. That’s right, not just a single color palette, multiple color palettes. While this might sound unnecessary first, it turns out that this is a very powerful setup to define themes in a very flexible way.

    Alright, but what color palettes are needed to compose a theme? As for Angular Material, it boils down to five different color palettes with each being used for different parts of the design:

    • Primary - Main colors most widely used across all screens and components.
    • Accent - Also known as the secondary color. Used for floating action buttons and interactive elements.
    • Warn - Colors to convey error state.
    • Foreground - Used for text and icons.
    • Background - Colors used for element backgrounds.

    If you want to dive deeper into the whole color usuability story in Material Design, we recommend checking out the Material Design Specification for colors, as it describes the topic in very deep detail.

    Using pre-built themes

    As mentioned earlier, Angular Material already comes with a set of pre-built themes that can be used right out of the box. Available pre-built themes are: , , and .

    Using them is as easy as including or importing the dedicated CSS file that comes with all Angular Material builds. So assuming we’ve installed Angular Material in our Angular CLI project using:

    We can go ahead and add any of the pre-built CSS files to our global styles by configuring our accordingly:

    Or, if we don’t want to fiddle around in our file, we can also import any pre-built theme right into the projects file like this:

    We can easily try it out by having our application using Angular Material components. So first we add to our ’s imports:

    Then we go ahead and render, for example, Angular Material’s tool bar component:

    md toolbar

    Looks cool right? Another thing that’s worth mentioning is that some Material components offer properties to configure whether they use the current theme’s primary, accent or warn color:

    md toolbar primary

    Custom theme using built-in color palettes

    Alright, using pre-built themes is a pretty cool thing as we get good looking components right away without doing any serious work. Let’s talk about how to create a custom theme using Angular Material’s predefined color palettes.

    In order to create a custom theme, we need to do a couple of things:

    • Generate core styles - These are theme independent styles, including styles for elevation levels, ripple effects, styles for accessibility and overlays
    • Primary color palette - Generate color palette for the theme’s primary color
    • Accent color palette - Generate color palette for the theme’s accent color
    • Warn color palette - Generate color palette for the theme’s warn color
    • Theme generation - Given the color palettes we generated, we create a theme, which can be used by Angular Material, or custom components

    While this looks like a lot of work, it turns out Angular Material gives us many tools to make these tasks a breeze. Let’s start off by creating a new file and import it in our root instead of the pre-built theme. After that we’ll go through the list step by step:

    Generate core styles

    This is a pretty easy one. Angular Material provides many very powerful SCSS mix-ins that do all the ground work for us. The mix-in that generates Material’s core styles is called . All we have to do is to import and call it.

    Here’s what that looks like (custom-theme.scss):

    Generate color palettes

    The next thing we need to do is to generate color palettes, which can then be composed to an actual theme. To generate a color palette, we can use Angular Material’s mix-in. takes a base palette (yes, that’s another palette, more on that in a second), and returns a new palette that comes with Material specific hue color values for “light”, “dark” and “contrast” colors of the given base palette.

    But what is this base palette? The base palette is just another color palette that compromises primary and accent colors of a single color. Wait, this sounds super confusing! Let’s take Material Design’s red color palette as an example:

    material design red palette

    Here we see all color codes for lighter and darker versions of the color red, as part of the Material Design specification. The values 50 - 900 represent the hue values or the “strength” of the color, or how light or dark it is. 500 is the recommended value for a theme’s primary color. There are much more defined color palettes and they are very nicely documented right here.

    So now that we know what a base palette is, we need to figure out how to create such a thing. Do we have to define and write them ourselves? The answer is yes and no. If we want to use our own custom color palettes, we need to define them manually. However, if we want to use any of Material Design colors, Angular Material comes with predefined palette definitions for all of them! If we take a quick look at the source code, we can see how to palette for the color red is implemented:

    It’s basically just a map where each key (tone value) maps to a color code. So if we ever want to define our own custom color palette, this is what it could look like.

    Okay, let’s create a palette for our primary, accent and warn colors. All we have to do is to call the mix-in with a base color palette. Let’s use for primary, for accent and for warn colors. We can simply reference these variables because we imported Angular Material’s theming capabilities in the previous step:

    Oh wait, what’s that? Why do we pass additional values to when generating our accent color palette? Well… Let’s take a closer look at what actually does.

    Understanding mat-palette

    We’ve already mentioned that generates a Material Design color palette out of a base color palette. But what does that actually mean? In order to get a better picture of what’s going on in that mix-in, let’s take a look at its source code:

    A mix-in is just a function - it takes arguments and returns something. takes a base color palette (which is a map like ) and optional default values for the generated color palette’s default, lighter and darker colors. Eventually it returns a new color palette that has some additional map values. Those additional values are the mentioned , and colors, as well as their corresponding , and colors. On top of that it generates keys for contrast values for each base hue tone (50 - 900).

    As we can see, we basically end up with a color palette that comes with everything the base palette provides, plus some additional keys for easy accessibility. So coming back to the question why we pass additional values to for our accent color, we now know that all we do is configuring the , and color tone.

    Generating themes

    A theme lets us apply a consistent tone to our application. It specifies the darkness of the surfaces, level of shadow and appropriate opacity of ink elements. The Material Design specification describes two different variations of themes - dark and light.

    Angular Material implements another set of mix-ins to generate either light or dark themes using and respectively. Now that we have all of our color palettes in place, we can do exactly that. Let’s create a light theme object like this:

    If we take a quick look at ’s source code, we can see that ti really just prepares another map object that can be later easily consumed for theming:

    That’s it! We can now use that generated theme object and feed it to Angular Material’s mix-in, which really just passes that theme object to other mix-ins for each component, so they can access the color values from there:

    Here’s the complete code for our custom theme, using and :

    Theming custom components

    There’s one thing we haven’t talked about yet: theming custom components. So far we’ve only changed the look and feel of Angular Material’s components. That’s because we’re calling the mix-in with our custom theme object. If we’d remove that call, we’d end up with all Material components in their base colors. This becomes more clear when we take a look at what does:

    Every component in Angular Material comes with a dedicated theme mix-in, that takes a theme object to access its values for theme specific styles. We can use exactly the same pattern to theme our own custom components. This turns out to be very powerful because it enables us to easily change a theme in our entire application just by changing the theme object!

    Let’s say we have a custom component as we created it in MachineLabs (a project you might want to check out!). renders a list of files and we want that component to respond to the configured theme. Here’s what its template looks like (simplified):

    It also comes with a base CSS file that introduces just enough styles so that the component is usable and accessible. No colors applied though. We won’t go into much detail here because there’s nothing new to learn. However, just to give a better idea, here are some corresponding base styles for :

    The component looks something like this:

    ml file tree

    We want to add theming capabilities to the following elements inside when a theme is applied:

    • needs a border in the “foreground” color of the configured theme
    • needs the theme’s background hover color when hovering over it
    • When is selected, we need to give it a lighter version of the theme’s primary color

    These rules can be easily implemented, simply by following the same pattern that Angular Material is using for its own components. We define a mix-in for that takes a theme object and uses that to access theme values using and mix-ins.

    Let’ start off by creating a mix-in and pull out the color palettes from the given theme we’re interested in (file-tree-theme.scss):

    Remember how created additional values for and for our theme? With we can access any value by its key of a given map. In other words, we’re pulling out color palettes for the theme’s primary, warn, background and foreground colors.

    Once that is done, we can start using color values of these color palettes in our style sheets using the mix-in. takes a color palette and a hue value (or one of the descriptive names like ) returns the color corresponding color. If we want to have a border in the divider foreground color of the given theme, it’d look something like this:

    We use exactly the same technique to theme the background color of like this:

    One thing to note here is that takes an optional third argument to configure the color’s opacity.

    That’s it! is now fully theme-aware and its look and feel responds to the configured theme. Here’s the complete code:

    And here’s what our component looks like now:

    ml file tree themed

    Last but not least, we have to call the mixing with our custom theme object. We do that by importing the mix-in in our file and execute it like this:

    In fact, we can take it one level further and create a meta theme mix-in that executes all theme mix-ins for our custom components, the same way Angular Material does it with . To do that we create a new mix-in , which would look like this:

    Here again, the complete code of our file:

    Conclusion

    Angular Material’s theming capabilities are very powerful and as of right now, it seems to be the only UI component library that gets it fairly right. Color palettes can be easily changed and reused and custom components can be enabled to consume a configured theme to match the look and feel of the entire application.

    Sours: https://blog.thoughtram.io/angular/2017/05/23/custom-themes-with-angular-material.html
    How to change the Angular material theme in just 5 minutes

    Custom Theme for Angular Material Components Series: Part 1 — Create a Theme

    Some time back, I was going through questions on stack-overflow. A question regarding applying same theme to as appeared at my feed. You can check the question here.

    Although I answered the question with sample code, I thought of expanding the same context to more components and make a nice formatted code-base. Which can be useful to my upcoming projects and yours, too.

    By end of this series, you would have an idea about creating and applying your own Custom Theme to Angular Material Components.

    Table of Contents

    Link to this section

    1. Create an Angular Project using Angular CLI and add Angular Material
    2. Understand Angular Material Custom Theme
    3. Create Base Theme Files
    4. Update Project Structure with few new modules
    5. Create basic UI skeleton

    1. Create an Angular Project using Angular CLI and add Angular Material

    Link to this section

    <>Copy

    ? will set our styling partner, i.e. , will skip generating 'spec.ts' files for our project and will not generate ( and ask about) routing module. You can learn more about CLI options here.

    Once it’s done...

    <>Copy

    Now, to add Angular Material, we will follow official guideline from Angular Material Getting Started:

    <>Copy

    The command will install Angular Material, the Component Dev Kit (CDK), Angular Animations and ask you the following questions to determine which features to include:

    1. Choose a prebuilt theme name, or "custom" for a custom theme: Select Custom
    2. Set up global Angular Material typography styles?: Yes
    3. Set up browser animations for Angular Material?: Yes

    The command will additionally perform the following configurations:

    • Add project dependencies to
    • Add the Roboto font to your
    • Add the Material Design icon font to your
    • Add a few global CSS styles to:
    • Remove margins from
    • Set on and
    • Set Roboto as the default application font

    You're done! Angular Material is now configured to be used in your application.

    2. Understand Angular Material Custom Theme

    Link to this section

    Let’s look at ? style.scss file:

    <>Copy

    Notice that Angular CLI has created a basic default theme for us. Below is the summary:

    1. Import material theme files and include core function
    2. Create primary , accent and warn colors from Material Color System.
    3. Using above colors, create a lighter version of theme with the help of mixin.
    4. Finally, include your custom theme in Angular Material’s Theme builder called , which is responsible for making all your components’ themes in-align with your custom theme.

    We will look into more details in next part.

    3. Create Base Theme Files

    Link to this section

    Now, for theme file, below is our target:

    1. Create default theme, I will keep this same as what we have in ? styles.scss.
    2. Create an alternate dark theme. We are going to have a theme-switcher UI, which will use default and dark themes.
    3. Create a typography config, just for headings ( , , etc). I am going to use for the same, you can change it if you want.

    Create a file called  ? theme.scss at ? src folder:

    <>Copy

    ? Angular's typography only works if content is wrapped within CSS class. Check your ? index.html file, class is added to tag. It was done when we ran .

    I will create one more file named ? custom-component-themes.scss like below:

    <>Copy

    Basically, this file will contain all of our components' themes.

    Let’s import both : ? theme.scss and ? custom-component-themes.scss in our main styles.scss and include their mixins, so our updated file will look like this:

    <>Copy

    One major thing we have added is that we have wrapped dark-theme colors inside a class selector called . What that means is, whenever you will load any themed component inside wrapper, it will use color palette.

    To understand more about use of Material Colors, checkout this color system guideline.

    4. Update Project Structure with few new modules

    Link to this section

    As of now, our project structure is something like below:

    Let’s create a module that has all of our Angular Material modules:

    <>Copy

    That will create a file and folder : ? material/material.module.ts. Let’s add some of modules from Angular Material to it:

    <>Copy

    Now, let’s create a shared module, which will be a home to all of our shared modules, components, directives, pipes and services.

    <>Copy

    ? Want to learn more about shared and core modules? Head out to official angular style guide.

    Now, let’s add our in array of :

    <>Copy

    And let’s import in :

    <>Copy

    5. Create basic UI skeleton

    Link to this section

    Let’s create a shared component which we will use in our :

    <>Copy

    Let’s update the content of ? sidenav.component.html , ? sidenav, component.scss and ? sidenav.component.ts:

    <>Copy

    Summary of ? sidenav.component.html:

    1. Create a wrapper , which will have theme handler classes. We are showing default theme without any class, but to show dark theme we will add class to it
    2. Create a button (with theme icon), which will toggle the theme. Basically, it should have only one job to do: toggle dark theme's flag. But, we will need something more than just a simple toggle, we will look this in class file
    3. Create a with color selection entries. This will help us change the color of
    4. Add some dummy menu entries in sidenav
    5. Finally, load the main content using

    <>Copy

    Summary of ? sidenav, component.scss:

    1. Give full height (minus height of ) to container, so that it takes full space of viewport (We just have , because is by default for blocks which has and is by default).
    2. Add padding to sidnav, so that content has some breathing space
    3. Capitalize content of . Becuase we are going to show dynamic color names, i.e. , and , we should capitalize it on UI.
    4. will help us to move theme switcher and menu to extreme right
    5. class will be added to radio icon in color selector menu, when that color is not selected. Instead of plain black, this should look fine.

    <>Copy

    Summary of ? sidenav.component.ts:

    1. : This will decide color of some components, in our case. This is getting change when user clicks on any color in toolbar menu.
    2. : This will give whole app light/dark theme look, look at the first line of sidenav.component.html in above snippets.
    3. : This will do below 2 things -
    • Toggle dark/light theme.
    • Since certain components (e.g. menu, select, dialog, etc.) are inside of a global overlay container, an additional step is required for those components to be affected by the theme's css class selector

    Let’s add to array of :

    <>Copy

    ? Don’t forget to export all the components/pipes/directives which we are going to make in .

    Now, let’s remove everything from ? app.component.html and replace it like below:

    <>Copy

    We shall also add some padding, so that it looks fine:

    <>Copy

    If you change theme and color from toolbar, you can see the result in browser:

    Now, the project structure is something like below:

    With this, we are done with below items:

    ✔️ Create an Angular Project using Angular CLI and add Angular Material

    ✔️ Understand Angular Material Custom Theme

    ✔️ Create Base Theme Files

    ✔️ Update Project Structure with few new modules

    ✔️ Create basic UI skeleton


    Thank You

    Link to this section

    for reading this article. This is my first article on indepth.dev. Let me know your feedback in comments section.

    Whatever we’ve created in this article, I have combined them as an Angular Project, and uploaded on GitHub shhdharmen/indepth-theming-material-components:

    repo card for shhdharmen/indepth-theming-material-components

    This was the first part of the series, below is the summary of upcoming articles:

    Part 2

    Link to this section

    Understand how Angular Material Theme works by taking a deep look into Angular Material’s repo.

    Part 3

    Link to this section

    1. Understand theme of
    2. Apply ’s theme to and
    3. Apply a different theme to and create nice styling for different kind of notifications (default, info, success, warning, error)

    That’s it, see you next time. And yes, always believe in yourself.

    Sours: https://indepth.dev/posts/1320/custom-theme-for-angular-material-components-series-part-1-create-a-theme

    Material change theme angular

    Angular: How to Use Multiple Themes with Material?

    This blog post is a tutorial on how to use multiple themes for an Angular11+ application with Material Design.

    We start from scratch by creating a new project and configuring the themes. Then we add a sample Card component to see what the themes look like and create a button to switch between Light and Dark themes.

    Finally, we discuss two solutions in order to apply a theme to the application body and to a custom component:

    Prerequisites

    The only prerequisite for this guide is to have installed Angular (version 11 or more) on your computer.

    Check out the official Angular documentation to know how to install it.

    Create a Project

    So let’s start by creating a new Angular project called material-themes by executing the command in a terminal:

    Note:

    You must select the SCSS option when asked Which stylesheet format would you like to use?.

    This creates a sample Angular application without any dependency. Read the next section to install the Material Design components library.

    Install Material Design

    Still in a terminal, execute the command to get to the created project and then:

    Several files are updated by this command, we will modify two of them later on:

    • Angular being a Single-page Application, the src/index.html is the only HTML file served by a web server for the whole application. All subsequent visual pages are displayed using Javascript,
    • The src/index.html file contains the global styles for our application. This is where we will define our themes.

    Configure the Themes

    Following the official Theming your Angular Material app documentation, we can update the src/styles.scss file to create two color themes:

    Each theme is using its own set of primary/accent/warn colors.

    • The is initialized with the SCSS function and will have dark font over white background,
    • On the contrary, the is initialized with the SCSS function and will have light font over dark background,
    • The dark theme is applied to any component inside an HTML tag with the CSS class.

    Components

    To apply the dark theme to the whole application, the trick is to add the dark-theme class to the root tag inside the file.

    But first let’s add a sample component to our application so that we can see what our themes looks like.

    Add a Sample Component

    The easiest way to do it is to copy/paste an example Card component taken from the Material documentation examples (plus I love Shiba dogs!):

    Update the src/app/app.component.html file to replace its default content by the Material card component:

    Don’t forget to also update the src/app/app.component.scss styles file:

    And more importantly to add MatCardModule and MatButtonModule modules to the application module imports (src/app/app.module.ts):

    Time to check the result: type the command in your terminal. The application should automatically open in your preferred web browser and display the following content:

    Shiba Light Theme

    Programmatically Switch to Dark Theme

    To check what it looks like in dark mode simply update the src/index.html file to set the dark-theme class on the html tag:

    The application should now display the card component with a darkish background:

    Shiba Light Theme

    Create a Theme Switching Button

    The theme selection should be up to the user though. Start by reverting the previous modifications to the src/index.html file in order to use the light theme by default.

    Then create a theme-switch component to allow the dynamic theme selection with the command .

    This component is a toggle button that sets/removes the dark-theme on the root html tag when clicked.

    Update the file src/app/theme-switch/theme-switch.component.html to:

    Update the file src/app/theme-switch/theme-switch.component.ts to:

    The document is injected in the component constructor and the element is retrieved by accessing the document.documentElement field. Then, adding or removing the dark-theme CSS class is simply done by using the classList property.

    Notes:

    Don’t forget to add the MatButtonToggleModule module to the src/app/app.module.ts file imports.

    You also need to update the src/app/app.component.html file to include the created theme-switch component: .

    Open the web application and click on the theme switch button to select the dark/light mode:

    Dark Theme With Light Background

    There is one issue though: the background remains white when switching to the dark theme! Let’s fix this using SCSS Mixins!

    Theming the Application Using SCSS Mixins

    Using SCSS Mixins is the recommended way to apply themes to your application in the Material documentation.

    Theming the App Background

    Update the src/styles.scss file to:

    • Create a body-theme mixin,
    • Use it both in the default light theme and the dark one.

    The body-theme mixin gets the default application background color from the given $theme parameter by using the mat-get and mat-color functions imported from the material library.

    The application in dark mode should now display a dark background as well as a dark card component:

    Dark Theme With Dark Background

    Theming your Own Component

    In this section we see how to apply theme colors to one of our own component.

    Create the Component

    Of course the first step is to create a component of our own. Here a dummy teapot component that displays “I’m a teapot!” in a bordered panel.

    Generate it using the following command:

    Update the src/app/teapot/teapot.component.html file:

    As well as the src/app/teapot/teapot.component.scss one:

    Finally, update the App component html to include our component (src/app/app.component.html):

    The application should look like this:

    Teapot without theme

    Create a Theme Mixin

    Time to apply color theming to this newly created component using SCSS mixin!

    First strip the file src/app/teapot/teapot.component.scss of color related styles:

    Then update the src/styles.scss root styles file to add a new mixin dedicated to our teapot component:

    The border now uses the primary color of the current theme. The text is displayed using the theme foreground color, and the background matches the theme’s.

    You should also update the default and dark themes to include this mixin:

    Reopen the application: switching from light to dark theme should update the teapot component accordingly:

    Teapot Light
    Teapot Dark

    Theming the Application Using CSS Variables

    IMO using SCSS mixins is not ideal to handle multiple custom Material themes!

    First you have all your theme related styles in a single src/styles.scss file. It can become quite big if you have many custom components. The other solution is to split this file in several smaller files, for example:

    • A material-variables.scss file that imports the material theming functions () and declare the two themes (),
    • A material-themes.scss file that includes the mat-core with and includes the theme styles for both the light and dark mode,
    • An app.scss that imports the material-themes.scss file (this must be done only once in the whole application) and declares other custom global themes.

    Then, each custom component that needs to get color values from the Material theme can include the material-variables.scss file and create the theme mixin here. This is harder to set up though.

    And you still have to get colors from the given theme for every custom component! This is tedious and creates many repetitions in your styles.

    A Single Mixin that Declares CSS Variables

    The idea is to have a single mixin dedicated to theme colors that initialize CSS3 variables. CSS variables are also known as custom properties or cascading variables.

    So let’s update the src/styles.scss file to create it:

    Here, the theme-colors mixin is created:

    • It fetches the various colors from the Material theme using map-get and mat-color functions,
    • It initializes several CSS variables with the syntax :
      • The value is set using String interpolation (The around the value), otherwise the SCSS variable name is written in the variable instead of its value,
      • The darken SCSS function is used to create a darker shade of the theme background.

    This mixin is used a usual in the default light theme as well as in the dark one if the CSS class dark-theme is set:

    Note:

    Here we use the syntax. It is a CSS pseudo-class that matches the root element of a tree representing the document (The element in our case).

    Theming the Body Background Color

    The body background color now uses the previously created CSS variable with the syntax :

    Theming our Custom Component

    You can also update the style of the teapot component (src/app/teapot/teapot.component.scss) to use these variables:

    The big advantage is that all the style for this component is now located in a single file, making it easier to maintain. Also, the variable values are only fetched from the theme once.

    There are a few drawbacks to this approach though:

    • You must declare all values in the mixin: for instance it is not possible to do as darken is an SCSS function executed when the files are compiled to CSS,
    • It can be hard to distinguish SCSS variables (compiled: their value is fixed during runtime) from CSS variables (that can be updated at runtime and are evaluated by the web browser).
    • I don’t know in what proportions but the CSS variables have an impact on performances when the browser renders your application.

    Conclusion

    Sources:

    The source code for this guide is available on GitHub at material-themes CSS variables for the version that uses CSS variables.
    The version based on SCSS mixins is available at material-themes mixins.

    So what’s you opinion regarding multiple themes usage in an Angular application? Would you rather use SCSS mixins or CSS variables? A mix of both maybe?

    Please leave a comment if you have any question or would like to suggest a better solution!

    Sours: https://octoperf.com/blog/2021/01/08/angular-material-multiple-themes/
    Angular Material Custom Theme Tutorial

    .

    You will also like:

    .



    39 40 41 42 43