how to use google material icons as class instead of <i> tag - google-material-icons

According to the guideline in the Google Material website we have to use material icons in _i _ tag.
the question is how to add the icons as font-awesome. something like :
Class="material-icons face"
instead of
<i class="material-icons"> face </i>

Yes,you can add the material icons as classes using the after pseudo elements.check out the fiddle
<span class="material-icons face"></span>
.face {
position:relative;
display:inline-block;
}
.face:after {
content: "face";
}

There's an easier way than the accepted answer. I got inspiration for this from the plugin css-toolip, which utilises the attr() css function (surprisingly has high browser adoption).
While attr() is supported for effectively all browsers for the content property...
https://caniuse.com/#search=css%20attr
<span class="material-icons" data-icon="face"></span>
.material-icons:after {
content: attr(data-icon);
}
This means that you don't have to add css for each icon that you want to use.

You can use IcoMoon (an outstanding free tool to generate fonts). Set class, prefix/suffix etc to adjust then you can easily add icons by <i class="m-home"></i>

It's also possible to create the selectors with Sass, if someone don't want to use data selectors.
$icons: "content_paste_search", "format-size", "search";
#each $icon in $icons {
.material-icons-#{$icon}:after {
content: $icon;
}
}
<span class="material-icons material-icons-search"></span>

Related

Angular: Mat-card keyboard navigation

I am trying to make a mat-card navigable from the keyboard. Right now, when pressing tab the element is focused however the redirect event (should be the same as the click event) isn't triggered when pressing enter.
I've tried keydown.enter and onKeyDown (from a11y package) but no success so far.
HTML
<mat-card role="group" (click)="addQueryParam(group.name)" (keydown.enter)="addQueryParam(group.name)" class="mat-elevation-z0"
[ngClass]="'background-'+index" (mouseout)="mouseOver=false"
(mouseover)="mouseOver=true" style="padding: none; margin: 5px">
Typescript
addQueryParam(groupName) {
this.router.navigate(['/data'], { queryParams: { ['groups.title']: groupName }, queryParamsHandling: 'merge' });
}
Any idea how to solve this issue?
TIA,
Isabela
I suggest you two things:
try using (keyup.enter)=.... I used it a couple of times and it worked well
If that doesn't work try using (keyup) or (keydown) and in your function check if the key code is 13 (enter key code), something like this:
HTML
<mat-card role="group" (click)="addQueryParam(group.name)" (keydown)="addQueryParam($event, group.name)" class="mat-elevation-z0"
[ngClass]="'background-'+index" (mouseout)="mouseOver=false"
(mouseover)="mouseOver=true" style="padding: none; margin: 5px">
Typescript:
addQueryParam($event, groupName) {
if($event.keyCode === 13){
this.router.navigate(['/data'], { queryParams: ...);
}
}
If i remember correctly you can check the type of the event in a field like event.type, or something like that.
Additionally check this discussion out, because theese functions are not well documented, and here you can find som infos :
What are the options for (keyup) in Angular2?
EDIT
I also found this very useful article: https://medium.com/claritydesignsystem/angular-pseudo-events-d4e7f89247ee

How to hide a matTooltip after set time interval?

I have looked at Angular official material design tooltip page, however, cannot seem to find anywhere how to hide a matTooltip after set time interval if a user stays on the object for a long period of time? Is there a separate in-built property for that? Or I'll need some kind of workaround?
It is imported into my TS file as described in the documentation and it works as it supposed to, thus I'm not adding that part of the code here.
My HTML is as follows:
<a matTooltip="Info about the action" matTooltipPosition="right">
<i class="fal-settings"></i> Settings
</a>
Template:
<a #actionInfoTooltip="matTooltip" matTooltip="Info about the action" matTooltipPosition="right" (mouseenter)="hideTooltipIn(actionInfoTooltip, 3000)">
<i class="fal-settings"></i> Settings
</a>
Component:
import { MatTooltip } from '#angular/material';
...
hideTooltipIn(tooltip : MatTooltip, ms : number){
setTimeout(() => tooltip.hide(), ms);
}
Use matTooltipHideDelay to add a delay before the tooltip is hidden. For your case:
<a matTooltip="Info about the action"
matTooltipPosition="right"
[matTooltipHideDelay]="3000">
<i class="fal-settings"></i> Settings
</a>
This will hide the tooltip after 3 seconds.

if.bind on a repeater - doesn't work in Edge & IE

I have the following html part of code:
<li repeat.for="route of router.navigation" style="border: 0px;" if.bind="showNav(route)">
<a href.bind="route.href" if.bind="!route.settings.nav">
${route.title}
</a>
<a href="javascript:;" if.bind="route.settings.nav">
${route.title}
</a>
<ul if.bind="route.settings.nav" class="dropdown-menu">
<li repeat.for="menu of route.settings.nav" class="ul-menu">
<a href.bind="menu.href">${menu.title}</a>
</li>
</ul>
</li>
In Opera, Chrome this code works fine, but in IE & Edge doesn't work - I don't see this HTML-part.
Problem is in the following statement (in the first line):
if.bind="showNav(route)"
If I deleted it, I can see my navigation menu in Edge & IE also.
Code for showNav:
showNav(row) {
if (!row.config.role) {
return true;
}
this.currentUserName = localStorage.getItem("token_user");
var currentUser = localStorage.getItem("token_role");
var role = row.config.role.includes(currentUser);
return role;
}
If I add in showNav
console.log(row);
It logs undefined in Edge & IE, but in Opera & Chrome I see the full necessary value.
I work with Aurelia framework, so route.navigation goes from ts-file and has the necessary value.
What could be the problem?
The github issue from #jesse-de-bruijne is different, that if.bind and repeat.for are not on the same DOM element. Furthermore, that issue was FIXED long time ago. But anyway, the show.bind purposed by Jesse works.
The real issue is that you are using if.bind and repeat.for on exact same DOM element, which is not supported by Aurelia due to uneven behavior from browsers. Aurelia documentation has not yet addressed this.
Besides the show.bind fix, you can also use template element (which will result to no extra DOM wrapper actually) to seperate repeat.for and if.bind.
<template> <!-- the top level template in your html file -->
...
<template repeat.for="route of router.navigation">
<li style="border: 0px;" if.bind="showNav(route)">
...
</li>
</template>
...
</template>
FYI: Repeat, with and if are called template controllers. They bind before other bindings. You cannot use multiple template controller attributes on the same dom element (because of different behavior among browsers).
The above comment is from Aurelia core member jdanyow on one of my issues.
https://github.com/aurelia/templating-resources/issues/252
Indeed, different browsers sort the HTML attributes differently. That's why your code works on some browsers but not all.
Try using a show.bind instead, if.bind has had some trouble with a repeater on the same line.
For example: https://github.com/aurelia/templating-resources/issues/84
If you do need to use an if.bind, for performance reasons for example, try putting a div child in the repeater containing said if.bind.

Dynamic styles for different user

I need dynamic styles for each user. The problem is such that it is possible to choose between two themes, one static and the other user can change. After change current user theme value will set to sass variable and need precompile. How I can do it?
It's better to rely on pure CSS features in this one rather than compile your SCSS on each request (which will be very inefficient).
Given this base SCSS file:
.base-theme {
.color-main {
color: $blue-lighter;
}
// and so on
}
You can use this like this:
<p class="color-main"> ... </p>
Based on settings stored in the database you can generate an alternative
theme like so:
<style>
.alt-theme .color-main {
color: <%= current_user.colors.main %>;
}
</style>
and apply them later like so:
<body class="<%= user.has_theme?? 'alt-theme' : 'base-theme' %>">...</body>

Reveal.js: Add fragments inside code

I've got a presentation running with reveal.js and everything is working. I am writing some sample code and highlight.js is working well within my presentation. But, I want to incrementally display code. E.g., imagine that I'm explaining a function to you, and I show you the first step, and then want to show the subsequent steps. Normally, I would use fragments to incrementally display items, but it's not working in a code block.
So I have something like this:
<pre><code>
def python_function()
<span class="fragment">display this first</span>
<span class="fragment">now display this</span>
</code></pre>
But the <span> elements are getting syntax-highlighted instead of read as HTML fragments. It looks something like this: http://imgur.com/nK3yNIS
FYI without the <span> elements highlight.js reads this correctly as python, but with the <span>, the language it detects is coffeescript.
Any ideas on how to have fragments inside a code block (or another way to simulate this) would be greatly appreciated.
To make fragments work in code snippets, you can now use the attribute data-noescape with the <code> tag
Source: Reveal.js docs
I got this to work. I had to change the init for the highlight.js dependency:
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() {
[].forEach.call( document.querySelectorAll( '.highlight' ), function( v, i) {
hljs.highlightBlock(v);
});
} },
Then I authored the section this way:
<section>
<h2>Demo</h2>
<pre class="stretch highlight cpp">
#pragma once
void step_one_setup(ofApp* app)
{
auto orbit_points = app-><span class="fragment zoom-in highlight-current-green">orbitPointsFromTimeInPeriod</span>(
app-><span class="fragment zoom-in highlight-current-green">timeInPeriodFromMilliseconds</span>(
app->updates.
<span class="fragment zoom-in highlight-current-green" data->milliseconds</span>()));
}
</pre>
</section>
Results:
I would try to use multiple <pre class="fragment">and change manually .reveal pre to margin: 0 auto; and box-shadow: none; so they will look like one block of code.
OR
Have you tried <code class="fragment">? If you use negative vertical margin to remove space between individual fragments and add the same background to <pre> as <code> has then you get what you want.
Result:

Resources